Game Development Community

1.1.3 GetWords() Bug Crashes OS

by Eric Robinson · in Torque Game Builder · 04/01/2007 (9:04 pm) · 1 replies

One line in script is enough to show the problem:
echo(getWords("This is a string.", 1, 0));
This bug causes cascading failure on my machine (Powerbook G4 running OSX 10.4.9). First TGB goes down. Next, my applications start failing. Lastly, the system becomes unresponsive and I have to turn it off by holding down the power button.

The problem is in lack of a bounds check. Certainly you should never ask for words the way I did (would be neat if that reversed the order of the words, though ;D). The problem is in the code here:
// consoleFunctions.cc approximately Line 315
static const char *getUnits(const char *string, S32 startIndex, S32 endIndex, const char *set)
{
   S32 sz;
   S32 index = startIndex;
   while(index--)
   {
      if(!*string)
         return "";
      sz = dStrcspn(string, set);
      if (string[sz] == 0)
         return "";
      string += (sz + 1);
   }
   const char *startString = string;
   while(startIndex <= endIndex--)
   {
      sz = dStrcspn(string, set);
      string += sz;
      if (*string == 0)
         break;
      string++;
   }
   if(!*string)
      string++;
   U32 totalSize = (U32(string - startString));
   char *ret = Con::getReturnBuffer(totalSize);
   dStrncpy(ret, startString, totalSize - 1);
   ret[totalSize-1] = '[[60c20b6407820]]';
   return ret;
}
getUnits() is used by the script functions getWords(), getFields(), and getRecords(). I haven't spent the time to decipher the function yet so I can't offer a fix. I'll post something if I can find the time to go through it. Zeroing in on this bug took quite a while and I've fallen behind a bit.

This came up because of a spelling mistake in one of my scripts. Dangerous bug, this.

#1
05/11/2007 (5:52 pm)
U32 totalSize = (U32(string - startString));

      ...

      dStrnCpy( ... );

As always with damn U32s if totalSize < 0 then it will wrap to somewhere around U32 max and dStrncpy will try and overwrite that amount of memory ;p

I've posted a fix for the next release - bug id #2998
Basically check that startIndex < endIndex at the beginning of the method and changed U32 to S32 just in case someone has ideas again.