Ver Fonte

Use strncat instead of strcat to prevent some buffer overflows

Glenn Smith há 7 anos atrás
pai
commit
7769da9434
32 ficheiros alterados com 147 adições e 134 exclusões
  1. 1 1
      Engine/source/T3D/shapeImage.cpp
  2. 3 3
      Engine/source/afx/arcaneFX.cpp
  3. 1 1
      Engine/source/afx/rpg/afxRPGMagicSpell.cpp
  4. 2 2
      Engine/source/app/net/net.cpp
  5. 11 11
      Engine/source/console/codeInterpreter.cpp
  6. 2 2
      Engine/source/console/compiledEval.cpp
  7. 2 2
      Engine/source/console/console.cpp
  8. 3 3
      Engine/source/console/consoleFunctions.cpp
  9. 9 9
      Engine/source/console/consoleInternal.cpp
  10. 6 6
      Engine/source/console/consoleObject.cpp
  11. 1 1
      Engine/source/console/fieldBrushObject.cpp
  12. 4 4
      Engine/source/console/persistenceManager.cpp
  13. 1 1
      Engine/source/console/scriptFilename.cpp
  14. 1 1
      Engine/source/console/simFieldDictionary.cpp
  15. 6 6
      Engine/source/console/simObject.cpp
  16. 5 5
      Engine/source/console/telnetDebugger.cpp
  17. 13 1
      Engine/source/core/strings/stringFunctions.h
  18. 3 3
      Engine/source/core/strings/stringUnit.cpp
  19. 1 1
      Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp
  20. 2 2
      Engine/source/gui/containers/guiFormCtrl.cpp
  21. 1 1
      Engine/source/gui/controls/guiDirectoryFileListCtrl.cpp
  22. 1 1
      Engine/source/gui/controls/guiListBoxCtrl.cpp
  23. 2 2
      Engine/source/gui/editor/guiFilterCtrl.cpp
  24. 4 4
      Engine/source/gui/worldEditor/terrainEditor.cpp
  25. 5 5
      Engine/source/materials/materialDefinition.cpp
  26. 2 2
      Engine/source/platform/profiler.cpp
  27. 1 1
      Engine/source/platformPOSIX/posixVolume.cpp
  28. 7 7
      Engine/source/platformWin32/winDInputDevice.cpp
  29. 5 4
      Engine/source/platformWin32/winFileio.cpp
  30. 39 39
      Engine/source/sim/actionMap.cpp
  31. 1 1
      Engine/source/sim/netStringTable.cpp
  32. 2 2
      Engine/source/terrain/terrData.cpp

+ 1 - 1
Engine/source/T3D/shapeImage.cpp

@@ -522,7 +522,7 @@ bool ShapeBaseImageData::preload(bool server, String &errorStr)
             if (stateSequence[j] && stateSequence[j][0] && stateSequenceRandomFlash[j]) {
             if (stateSequence[j] && stateSequence[j][0] && stateSequenceRandomFlash[j]) {
                char bufferVis[128];
                char bufferVis[128];
                dStrncpy(bufferVis, stateSequence[j], 100);
                dStrncpy(bufferVis, stateSequence[j], 100);
-               dStrcat(bufferVis, "_vis");
+               dStrcat(bufferVis, "_vis", 128);
                s.sequenceVis[i] = shape[i]->findSequence(bufferVis);
                s.sequenceVis[i] = shape[i]->findSequence(bufferVis);
             }
             }
             if (s.sequenceVis[i] != -1)
             if (s.sequenceVis[i] != -1)

+ 3 - 3
Engine/source/afx/arcaneFX.cpp

@@ -908,7 +908,7 @@ ConsoleFunction(echoThru, const char*, 2, 0, "(string passthru, string text...)"
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 2; i < argc; i++)
    for(i = 2; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::printf("%s -- [%s]", ret, argv[1].getStringValue());
    Con::printf("%s -- [%s]", ret, argv[1].getStringValue());
    ret[0] = 0;
    ret[0] = 0;
@@ -928,7 +928,7 @@ ConsoleFunction(warnThru, const char*, 2, 0, "(string passthru, string text...)"
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 2; i < argc; i++)
    for(i = 2; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::warnf("%s -- [%s]", ret, argv[1].getStringValue());
    Con::warnf("%s -- [%s]", ret, argv[1].getStringValue());
    ret[0] = 0;
    ret[0] = 0;
@@ -948,7 +948,7 @@ ConsoleFunction(errorThru, const char*, 2, 0, "(string passthru, string text...)
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 2; i < argc; i++)
    for(i = 2; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::errorf("%s -- [%s]", ret, argv[1].getStringValue());
    Con::errorf("%s -- [%s]", ret, argv[1].getStringValue());
    ret[0] = 0;
    ret[0] = 0;

+ 1 - 1
Engine/source/afx/rpg/afxRPGMagicSpell.cpp

@@ -227,7 +227,7 @@ char* afxRPGMagicSpellData::formatDesc(char* buffer, int len) const
       {
       {
         dStrcpy(target_str, _afxRPGMagicSpell_TargetType::_sEnumTable[i].mName);
         dStrcpy(target_str, _afxRPGMagicSpell_TargetType::_sEnumTable[i].mName);
         if (spell_target != TARGET_FREE && target_optional)
         if (spell_target != TARGET_FREE && target_optional)
-          dStrcat(target_str, " (opt)");
+          dStrcat(target_str, " (opt)", 32);
       }
       }
       break;
       break;
     }
     }

+ 2 - 2
Engine/source/app/net/net.cpp

@@ -129,7 +129,7 @@
       if(conn->isConnectionToServer())
       if(conn->isConnectionToServer())
       {
       {
          dStrcpy(mBuf, "clientCmd");
          dStrcpy(mBuf, "clientCmd");
-         dStrcat(mBuf, rmtCommandName);
+         dStrcat(mBuf, rmtCommandName, 1024);
 
 
          char *temp = mArgv[1];
          char *temp = mArgv[1];
          mArgv[1] = mBuf;
          mArgv[1] = mBuf;
@@ -140,7 +140,7 @@
       else
       else
       {
       {
          dStrcpy(mBuf, "serverCmd");
          dStrcpy(mBuf, "serverCmd");
-         dStrcat(mBuf, rmtCommandName);
+         dStrcat(mBuf, rmtCommandName, 1024);
          char *temp = mArgv[1];
          char *temp = mArgv[1];
 
 
          dSprintf(idBuf, sizeof(idBuf), "%d", conn->getId());
          dSprintf(idBuf, sizeof(idBuf), "%d", conn->getId());

+ 11 - 11
Engine/source/console/codeInterpreter.cpp

@@ -420,13 +420,13 @@ exitLabel:
       if (gEvalState.traceOn)
       if (gEvalState.traceOn)
       {
       {
          sTraceBuffer[0] = 0;
          sTraceBuffer[0] = 0;
-         dStrcat(sTraceBuffer, "Leaving ");
+         dStrcat(sTraceBuffer, "Leaving ", 1024);
 
 
          if (packageName)
          if (packageName)
          {
          {
-            dStrcat(sTraceBuffer, "[");
-            dStrcat(sTraceBuffer, packageName);
-            dStrcat(sTraceBuffer, "]");
+            dStrcat(sTraceBuffer, "[", 1024);
+            dStrcat(sTraceBuffer, packageName, 1024);
+            dStrcat(sTraceBuffer, "]", 1024);
          }
          }
          if (thisNamespace && thisNamespace->mName)
          if (thisNamespace && thisNamespace->mName)
          {
          {
@@ -471,13 +471,13 @@ void CodeInterpreter::parseArgs(U32 &ip)
       if (gEvalState.traceOn)
       if (gEvalState.traceOn)
       {
       {
          sTraceBuffer[0] = 0;
          sTraceBuffer[0] = 0;
-         dStrcat(sTraceBuffer, "Entering ");
+         dStrcat(sTraceBuffer, "Entering ", 1024);
 
 
          if (mExec.packageName)
          if (mExec.packageName)
          {
          {
-            dStrcat(sTraceBuffer, "[");
-            dStrcat(sTraceBuffer, mExec.packageName);
-            dStrcat(sTraceBuffer, "]");
+            dStrcat(sTraceBuffer, "[", 1024);
+            dStrcat(sTraceBuffer, mExec.packageName, 1024);
+            dStrcat(sTraceBuffer, "]", 1024);
          }
          }
          if (mExec.thisNamespace && mExec.thisNamespace->mName)
          if (mExec.thisNamespace && mExec.thisNamespace->mName)
          {
          {
@@ -491,11 +491,11 @@ void CodeInterpreter::parseArgs(U32 &ip)
          }
          }
          for (S32 i = 0; i < wantedArgc; i++)
          for (S32 i = 0; i < wantedArgc; i++)
          {
          {
-            dStrcat(sTraceBuffer, mExec.argv[i + 1]);
+            dStrcat(sTraceBuffer, mExec.argv[i + 1], 1024);
             if (i != wantedArgc - 1)
             if (i != wantedArgc - 1)
-               dStrcat(sTraceBuffer, ", ");
+               dStrcat(sTraceBuffer, ", ", 1024);
          }
          }
-         dStrcat(sTraceBuffer, ")");
+         dStrcat(sTraceBuffer, ")", 1024);
          Con::printf("%s", sTraceBuffer);
          Con::printf("%s", sTraceBuffer);
       }
       }
 
 

+ 2 - 2
Engine/source/console/compiledEval.cpp

@@ -70,9 +70,9 @@ namespace Con
       ret[0] = 0;
       ret[0] = 0;
       for (walk = ns; walk; walk = walk->mParent)
       for (walk = ns; walk; walk = walk->mParent)
       {
       {
-         dStrcat(ret, walk->mName);
+         dStrcat(ret, walk->mName, size);
          if (walk->mParent)
          if (walk->mParent)
-            dStrcat(ret, " -> ");
+            dStrcat(ret, " -> ", size);
       }
       }
       return ret;
       return ret;
    }
    }

+ 2 - 2
Engine/source/console/console.cpp

@@ -2176,8 +2176,8 @@ bool expandPath(char* pDstPath, U32 size, const char* pSrcPath, const char* pWor
       }
       }
 
 
       // Format the output path.
       // Format the output path.
-      dStrncat(pathBuffer, "/", sizeof(pathBuffer) - 1 - strlen(pathBuffer));
-      dStrncat(pathBuffer, pSrc, sizeof(pathBuffer) - 1 - strlen(pathBuffer));
+      dStrcat(pathBuffer, "/", sizeof(pathBuffer) - 1 - strlen(pathBuffer));
+      dStrcat(pathBuffer, pSrc, sizeof(pathBuffer) - 1 - strlen(pathBuffer));
 
 
       // Are we ensuring the trailing slash?
       // Are we ensuring the trailing slash?
       if (ensureTrailingSlash)
       if (ensureTrailingSlash)

+ 3 - 3
Engine/source/console/consoleFunctions.cpp

@@ -1889,7 +1889,7 @@ ConsoleFunction( echo, void, 2, 0, "( string message... ) "
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 1; i < argc; i++)
    for(i = 1; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::printf("%s", ret);
    Con::printf("%s", ret);
    ret[0] = 0;
    ret[0] = 0;
@@ -1913,7 +1913,7 @@ ConsoleFunction( warn, void, 2, 0, "( string message... ) "
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 1; i < argc; i++)
    for(i = 1; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::warnf(ConsoleLogEntry::General, "%s", ret);
    Con::warnf(ConsoleLogEntry::General, "%s", ret);
    ret[0] = 0;
    ret[0] = 0;
@@ -1937,7 +1937,7 @@ ConsoleFunction( error, void, 2, 0, "( string message... ) "
    char *ret = Con::getReturnBuffer(len + 1);
    char *ret = Con::getReturnBuffer(len + 1);
    ret[0] = 0;
    ret[0] = 0;
    for(i = 1; i < argc; i++)
    for(i = 1; i < argc; i++)
-      dStrcat(ret, argv[i]);
+      dStrcat(ret, argv[i], len);
 
 
    Con::errorf(ConsoleLogEntry::General, "%s", ret);
    Con::errorf(ConsoleLogEntry::General, "%s", ret);
    ret[0] = 0;
    ret[0] = 0;

+ 9 - 9
Engine/source/console/consoleInternal.cpp

@@ -900,21 +900,21 @@ DefineEngineFunction(backtrace, void, (), ,
    buf[0] = 0;
    buf[0] = 0;
    for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
    for (U32 i = 0; i < gEvalState.getStackDepth(); i++)
    {
    {
-      dStrcat(buf, "->");
+      dStrcat(buf, "->", totalSize);
 
 
       if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
       if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage)
       {
       {
-         dStrcat(buf, "[");
-         dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage);
-         dStrcat(buf, "]");
+         dStrcat(buf, "[", totalSize);
+         dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mEntryList->mPackage, totalSize);
+         dStrcat(buf, "]", totalSize);
       }
       }
       if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
       if (gEvalState.stack[i]->scopeNamespace && gEvalState.stack[i]->scopeNamespace->mName)
       {
       {
-         dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName);
-         dStrcat(buf, "::");
+         dStrcat(buf, gEvalState.stack[i]->scopeNamespace->mName, totalSize);
+         dStrcat(buf, "::", totalSize);
       }
       }
       if (gEvalState.stack[i]->scopeName)
       if (gEvalState.stack[i]->scopeName)
-         dStrcat(buf, gEvalState.stack[i]->scopeName);
+         dStrcat(buf, gEvalState.stack[i]->scopeName, totalSize);
    }
    }
 
 
    Con::printf("BackTrace: %s", buf);
    Con::printf("BackTrace: %s", buf);
@@ -1362,7 +1362,7 @@ void Namespace::addScriptCallback(const char *funcName, const char *usage, Conso
    char lilBuffer[32];
    char lilBuffer[32];
    dStrcpy(buffer, funcName);
    dStrcpy(buffer, funcName);
    dSprintf(lilBuffer, 32, "_%d_cb", uid++);
    dSprintf(lilBuffer, 32, "_%d_cb", uid++);
-   dStrcat(buffer, lilBuffer);
+   dStrcat(buffer, lilBuffer, 1024);
 
 
    Entry *ent = createLocalEntry(StringTable->insert(buffer));
    Entry *ent = createLocalEntry(StringTable->insert(buffer));
    trashCache();
    trashCache();
@@ -1383,7 +1383,7 @@ void Namespace::markGroup(const char* name, const char* usage)
    char lilBuffer[32];
    char lilBuffer[32];
    dStrcpy(buffer, name);
    dStrcpy(buffer, name);
    dSprintf(lilBuffer, 32, "_%d", uid++);
    dSprintf(lilBuffer, 32, "_%d", uid++);
-   dStrcat(buffer, lilBuffer);
+   dStrcat(buffer, lilBuffer, 1024);
 
 
    Entry *ent = createLocalEntry(StringTable->insert(buffer));
    Entry *ent = createLocalEntry(StringTable->insert(buffer));
    trashCache();
    trashCache();

+ 6 - 6
Engine/source/console/consoleObject.cpp

@@ -356,7 +356,7 @@ void ConsoleObject::addGroup(const char* in_pGroupname, const char* in_pGroupDoc
    char* pFieldNameBuf = suppressSpaces(in_pGroupname);
    char* pFieldNameBuf = suppressSpaces(in_pGroupname);
 
 
    // Append group type to fieldname.
    // Append group type to fieldname.
-   dStrcat(pFieldNameBuf, "_begingroup");
+   dStrcat(pFieldNameBuf, "_begingroup", 1024);
 
 
    // Create Field.
    // Create Field.
    AbstractClassRep::Field f;
    AbstractClassRep::Field f;
@@ -385,7 +385,7 @@ void ConsoleObject::endGroup(const char*  in_pGroupname)
    char* pFieldNameBuf = suppressSpaces(in_pGroupname);
    char* pFieldNameBuf = suppressSpaces(in_pGroupname);
 
 
    // Append group type to fieldname.
    // Append group type to fieldname.
-   dStrcat(pFieldNameBuf, "_endgroup");
+   dStrcat(pFieldNameBuf, "_endgroup", 1024);
 
 
    // Create Field.
    // Create Field.
    AbstractClassRep::Field f;
    AbstractClassRep::Field f;
@@ -407,7 +407,7 @@ void ConsoleObject::endGroup(const char*  in_pGroupname)
 void ConsoleObject::addArray( const char *arrayName, S32 count )
 void ConsoleObject::addArray( const char *arrayName, S32 count )
 {
 {
    char *nameBuff = suppressSpaces(arrayName);
    char *nameBuff = suppressSpaces(arrayName);
-   dStrcat(nameBuff, "_beginarray");
+   dStrcat(nameBuff, "_beginarray", 1024);
 
 
    // Create Field.
    // Create Field.
    AbstractClassRep::Field f;
    AbstractClassRep::Field f;
@@ -430,7 +430,7 @@ void ConsoleObject::addArray( const char *arrayName, S32 count )
 void ConsoleObject::endArray( const char *arrayName )
 void ConsoleObject::endArray( const char *arrayName )
 {
 {
    char *nameBuff = suppressSpaces(arrayName);
    char *nameBuff = suppressSpaces(arrayName);
-   dStrcat(nameBuff, "_endarray");
+   dStrcat(nameBuff, "_endarray", 1024);
 
 
    // Create Field.
    // Create Field.
    AbstractClassRep::Field f;
    AbstractClassRep::Field f;
@@ -776,8 +776,8 @@ static const char* returnClassList( Vector< AbstractClassRep* >& classes, U32 bu
    dStrcpy( ret, classes[ 0 ]->getClassName() );
    dStrcpy( ret, classes[ 0 ]->getClassName() );
    for( U32 i = 1; i < classes.size(); i ++ )
    for( U32 i = 1; i < classes.size(); i ++ )
    {
    {
-      dStrcat( ret, "\t" );
-      dStrcat( ret, classes[ i ]->getClassName() );
+      dStrcat( ret, "\t", bufSize );
+      dStrcat( ret, classes[ i ]->getClassName(), bufSize );
    }
    }
    
    
    return ret;
    return ret;

+ 1 - 1
Engine/source/console/fieldBrushObject.cpp

@@ -275,7 +275,7 @@ DefineConsoleMethod(FieldBrushObject, queryFields, const char*, (const char* sim
         // Copy string element.
         // Copy string element.
         dStrcpy( tempBuf, StringUnit::getUnit( groupList, groupIndex, " \t\n" ) );
         dStrcpy( tempBuf, StringUnit::getUnit( groupList, groupIndex, " \t\n" ) );
         // Append internal name.
         // Append internal name.
-        dStrcat( tempBuf, "_begingroup" );
+        dStrcat( tempBuf, "_begingroup", 256 );
         // Store Group.
         // Store Group.
         groups.push_back( StringTable->insert( tempBuf ) );
         groups.push_back( StringTable->insert( tempBuf ) );
     }
     }

+ 4 - 4
Engine/source/console/persistenceManager.cpp

@@ -967,10 +967,10 @@ void PersistenceManager::updateToken( const U32 lineNumber, const U32 linePositi
 
 
    // Build the new line with the
    // Build the new line with the
    // preString + newValue + postString
    // preString + newValue + postString
-   dStrcat(newLine, preString);
+   dStrcat(newLine, preString, newLineLen);
    if ( newValue )
    if ( newValue )
-      dStrcat(newLine, newValue);
-   dStrcat(newLine, postString);
+      dStrcat(newLine, newValue, newLineLen);
+   dStrcat(newLine, postString, newLineLen);
 
 
    // Clear our existing line
    // Clear our existing line
    if (mLineBuffer[lineNumber])
    if (mLineBuffer[lineNumber])
@@ -1243,7 +1243,7 @@ PersistenceManager::ParsedObject* PersistenceManager::writeNewObject(SimObject*
    char* indent = getObjectIndent(parentObject);
    char* indent = getObjectIndent(parentObject);
 
 
    if (parentObject)
    if (parentObject)
-      dStrcat(indent, "   \0");
+      dStrcat(indent, "   \0", 2048);
 
 
    // Write out the beginning of the object declaration
    // Write out the beginning of the object declaration
    const char* dclToken = "new";
    const char* dclToken = "new";

+ 1 - 1
Engine/source/console/scriptFilename.cpp

@@ -325,7 +325,7 @@ bool collapseScriptFilename(char *filename, U32 size, const char *src)
       *filename = 0;
       *filename = 0;
       if(*test[i].replace)
       if(*test[i].replace)
          dSprintf(filename, size, "%s/", test[i].replace);
          dSprintf(filename, size, "%s/", test[i].replace);
-      dStrcat(filename, rel);
+      dStrcat(filename, rel, size);
       return true;
       return true;
    }
    }
 
 

+ 1 - 1
Engine/source/console/simFieldDictionary.cpp

@@ -281,7 +281,7 @@ void SimFieldDictionary::writeFields(SimObject *obj, Stream &stream, U32 tabStop
       dSprintf(expandedBuffer, nBufferSize, "%s%s%s = \"", typeName, *typeName ? " " : "", (*itr)->slotName);
       dSprintf(expandedBuffer, nBufferSize, "%s%s%s = \"", typeName, *typeName ? " " : "", (*itr)->slotName);
       if ((*itr)->value)
       if ((*itr)->value)
          expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), (*itr)->value);
          expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), (*itr)->value);
-      dStrcat(expandedBuffer, "\";\r\n");
+      dStrcat(expandedBuffer, "\";\r\n", nBufferSize);
 
 
       stream.write(dStrlen(expandedBuffer), expandedBuffer);
       stream.write(dStrlen(expandedBuffer), expandedBuffer);
    }
    }

+ 6 - 6
Engine/source/console/simObject.cpp

@@ -347,7 +347,7 @@ void SimObject::writeFields(Stream &stream, U32 tabStop)
          }
          }
 
 
          expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), val);
          expandEscape((char*)expandedBuffer + dStrlen(expandedBuffer), val);
-         dStrcat(expandedBuffer, "\";\r\n");
+         dStrcat(expandedBuffer, "\";\r\n", expandedBufferSize);
 
 
          stream.writeTabs(tabStop);
          stream.writeTabs(tabStop);
          stream.write(dStrlen(expandedBuffer),expandedBuffer);
          stream.write(dStrlen(expandedBuffer),expandedBuffer);
@@ -1029,7 +1029,7 @@ void SimObject::setDataField(StringTableEntry slotName, const char *array, const
       {
       {
          char buf[256];
          char buf[256];
          dStrcpy(buf, slotName);
          dStrcpy(buf, slotName);
-         dStrcat(buf, array);
+         dStrcat(buf, array, 256);
          StringTableEntry permanentSlotName = StringTable->insert(buf);
          StringTableEntry permanentSlotName = StringTable->insert(buf);
          mFieldDictionary->setFieldValue(permanentSlotName, value);
          mFieldDictionary->setFieldValue(permanentSlotName, value);
          onDynamicModified( permanentSlotName, value );
          onDynamicModified( permanentSlotName, value );
@@ -1070,7 +1070,7 @@ const char *SimObject::getDataField(StringTableEntry slotName, const char *array
       {
       {
          static char buf[256];
          static char buf[256];
          dStrcpy(buf, slotName);
          dStrcpy(buf, slotName);
-         dStrcat(buf, array);
+         dStrcat(buf, array, 256);
          if (const char* val = mFieldDictionary->getFieldValue(StringTable->insert(buf)))
          if (const char* val = mFieldDictionary->getFieldValue(StringTable->insert(buf)))
             return val;
             return val;
       }
       }
@@ -1311,7 +1311,7 @@ U32 SimObject::getDataFieldType( StringTableEntry slotName, const char* array )
    {
    {
       static char buf[256];
       static char buf[256];
       dStrcpy( buf, slotName );
       dStrcpy( buf, slotName );
-      dStrcat( buf, array );
+      dStrcat( buf, array, 256 );
 
 
       return mFieldDictionary->getFieldType( StringTable->insert( buf ) );
       return mFieldDictionary->getFieldType( StringTable->insert( buf ) );
    }
    }
@@ -1334,7 +1334,7 @@ void SimObject::setDataFieldType(const U32 fieldTypeId, StringTableEntry slotNam
    {
    {
       static char buf[256];
       static char buf[256];
       dStrcpy( buf, slotName );
       dStrcpy( buf, slotName );
-      dStrcat( buf, array );
+      dStrcat( buf, array, 256 );
 
 
       mFieldDictionary->setFieldType( StringTable->insert( buf ), fieldTypeId );
       mFieldDictionary->setFieldType( StringTable->insert( buf ), fieldTypeId );
       onDynamicModified( slotName, mFieldDictionary->getFieldValue(slotName) );
       onDynamicModified( slotName, mFieldDictionary->getFieldValue(slotName) );
@@ -1355,7 +1355,7 @@ void SimObject::setDataFieldType(const char *typeName, StringTableEntry slotName
    {
    {
       static char buf[256];
       static char buf[256];
       dStrcpy( buf, slotName );
       dStrcpy( buf, slotName );
-      dStrcat( buf, array );
+      dStrcat( buf, array, 256 );
       StringTableEntry permanentSlotName = StringTable->insert(buf);
       StringTableEntry permanentSlotName = StringTable->insert(buf);
 
 
       mFieldDictionary->setFieldType( permanentSlotName, typeName );
       mFieldDictionary->setFieldType( permanentSlotName, typeName );

+ 5 - 5
Engine/source/console/telnetDebugger.cpp

@@ -470,19 +470,19 @@ void TelnetDebugger::sendBreak()
       if ( ns ) {
       if ( ns ) {
 
 
          if ( ns->mParent && ns->mParent->mPackage && ns->mParent->mPackage[0] ) {
          if ( ns->mParent && ns->mParent->mPackage && ns->mParent->mPackage[0] ) {
-            dStrcat( scope, ns->mParent->mPackage );
-            dStrcat( scope, "::" );
+            dStrcat( scope, ns->mParent->mPackage, MaxCommandSize );
+            dStrcat( scope, "::", MaxCommandSize );
          }
          }
          if ( ns->mName && ns->mName[0] ) {
          if ( ns->mName && ns->mName[0] ) {
-            dStrcat( scope, ns->mName );
-            dStrcat( scope, "::" );
+            dStrcat( scope, ns->mName, MaxCommandSize );
+            dStrcat( scope, "::", MaxCommandSize );
          }
          }
       }
       }
 
 
       const char *function = gEvalState.stack[i]->scopeName;
       const char *function = gEvalState.stack[i]->scopeName;
       if ((!function) || (!function[0]))
       if ((!function) || (!function[0]))
          function = "<none>";
          function = "<none>";
-      dStrcat( scope, function );
+      dStrcat( scope, function, MaxCommandSize );
 
 
       U32 line=0, inst;
       U32 line=0, inst;
       U32 ip = gEvalState.stack[i]->ip;
       U32 ip = gEvalState.stack[i]->ip;

+ 13 - 1
Engine/source/core/strings/stringFunctions.h

@@ -32,6 +32,10 @@
 #include "platform/types.h"
 #include "platform/types.h"
 #endif
 #endif
 
 
+#ifndef _PLATFORMASSERT_H_
+#include "platform/platformAssert.h"
+#endif
+
 #if defined(TORQUE_OS_WIN)
 #if defined(TORQUE_OS_WIN)
 // These standard functions are not defined on Win32 and other Microsoft platforms...
 // These standard functions are not defined on Win32 and other Microsoft platforms...
 #define strcasecmp   _stricmp
 #define strcasecmp   _stricmp
@@ -47,14 +51,22 @@
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 // standard string functions [defined in platformString.cpp]
 // standard string functions [defined in platformString.cpp]
 
 
+/// @deprecated Use dStrcat(char *, const char *, dsize_t) instead
 inline char *dStrcat(char *dst, const char *src)
 inline char *dStrcat(char *dst, const char *src)
 {
 {
+   AssertFatal(false, "dStrcat without length is deprecated");
    return strcat(dst,src);
    return strcat(dst,src);
 }   
 }   
 
 
+inline char *dStrcat(char *dst, const char *src, dsize_t len)
+{
+   return strncat(dst,src,len - 1); //Safety because strncat copies at most len+1 characters
+}
+
 inline char *dStrncat(char *dst, const char *src, dsize_t len)
 inline char *dStrncat(char *dst, const char *src, dsize_t len)
 {
 {
-   return strncat(dst,src,len);
+   AssertFatal(false, "Use dStrcat with length");
+   return dStrcat(dst, src, len);
 }
 }
 
 
 inline S32  dStrcmp(const char *str1, const char *str2)
 inline S32  dStrcmp(const char *str1, const char *str2)

+ 3 - 3
Engine/source/core/strings/stringUnit.cpp

@@ -164,7 +164,7 @@ namespace StringUnit
 
 
       // replace this unit
       // replace this unit
       ret[sz] = '\0';
       ret[sz] = '\0';
-      dStrcat(ret, replace);
+      dStrcat(ret, replace, 2048);
 
 
       // copy remaining chunks
       // copy remaining chunks
       sz = dStrcspn(string, set);         // skip chunk we're replacing
       sz = dStrcspn(string, set);         // skip chunk we're replacing
@@ -172,7 +172,7 @@ namespace StringUnit
          return ret;
          return ret;
 
 
       string += sz;
       string += sz;
-      dStrcat(ret, string);
+      dStrcat(ret, string, 2048);
       return ret;
       return ret;
    }
    }
 
 
@@ -211,7 +211,7 @@ namespace StringUnit
       }
       }
 
 
       string += sz + 1; // skip the extra field delimiter
       string += sz + 1; // skip the extra field delimiter
-      dStrcat(ret, string);
+      dStrcat(ret, string, 2048);
       return ret;
       return ret;
    }
    }
 }
 }

+ 1 - 1
Engine/source/gfx/gl/sdl/gfxGLDevice.sdl.cpp

@@ -129,7 +129,7 @@ void GFXGLDevice::enumerateAdapters( Vector<GFXAdapter*> &adapterList )
    if (renderer)
    if (renderer)
    {
    {
       dStrcpy(toAdd->mName, renderer);
       dStrcpy(toAdd->mName, renderer);
-      dStrncat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen);
+      dStrcat(toAdd->mName, " OpenGL", GFXAdapter::MaxAdapterNameLen);
    }
    }
    else
    else
       dStrcpy(toAdd->mName, "OpenGL");
       dStrcpy(toAdd->mName, "OpenGL");

+ 2 - 2
Engine/source/gui/containers/guiFormCtrl.cpp

@@ -219,8 +219,8 @@ bool GuiFormCtrl::resize(const Point2I &newPosition, const Point2I &newExtent)
       for(S32 i=strlen; i>=0; --i)
       for(S32 i=strlen; i>=0; --i)
       {
       {
          dStrcpy(buf, "");
          dStrcpy(buf, "");
-         dStrncat(buf, (const char*)mCaption, i);
-         dStrcat(buf, "...");
+         dStrcat(buf, (const char*)mCaption, i);
+         dStrcat(buf, "...", i);
 
 
          textWidth = mProfile->mFont->getStrWidth(buf);
          textWidth = mProfile->mFont->getStrWidth(buf);
 
 

+ 1 - 1
Engine/source/gui/controls/guiDirectoryFileListCtrl.cpp

@@ -195,7 +195,7 @@ DefineEngineMethod( GuiDirectoryFileListCtrl, getSelectedFiles, const char*, (),
 
 
       dMemset( itemBuffer, 0, itemBufSize );
       dMemset( itemBuffer, 0, itemBufSize );
       dSprintf( itemBuffer, itemBufSize, " %s", itemText );
       dSprintf( itemBuffer, itemBufSize, " %s", itemText );
-      dStrcat( returnBuffer, itemBuffer );
+      dStrcat( returnBuffer, itemBuffer, itemBufSize );
    }
    }
 
 
    return returnBuffer;
    return returnBuffer;

+ 1 - 1
Engine/source/gui/controls/guiListBoxCtrl.cpp

@@ -458,7 +458,7 @@ DefineEngineMethod( GuiListBoxCtrl, getSelectedItems, const char*, (),,
    {
    {
       UTF8 retFormat[12];
       UTF8 retFormat[12];
       dSprintf( retFormat, 12, "%d ", (*i) );
       dSprintf( retFormat, 12, "%d ", (*i) );
-      dStrcat( retBuffer, retFormat );
+      dStrcat( retBuffer, retFormat, 12 );
    }
    }
 
 
    return retBuffer;
    return retBuffer;

+ 2 - 2
Engine/source/gui/editor/guiFilterCtrl.cpp

@@ -70,8 +70,8 @@ DefineConsoleMethod( GuiFilterCtrl, getValue, const char*, (), , "Return a tuple
    for (U32 i=0; i < filter->size(); i++)
    for (U32 i=0; i < filter->size(); i++)
    {
    {
       char value[32];
       char value[32];
-      dSprintf(value, 31, "%1.5f ", *(filter->begin()+i) );
-      dStrcat(buffer, value);
+      dSprintf(value, 32, "%1.5f ", *(filter->begin()+i) );
+      dStrcat(buffer, value, 32);
    }
    }
 
 
    return buffer;
    return buffer;

+ 4 - 4
Engine/source/gui/worldEditor/terrainEditor.cpp

@@ -2495,8 +2495,8 @@ DefineConsoleMethod(TerrainEditor, getTerrainBlocksMaterialList, const char *, (
    ret[0] = 0;
    ret[0] = 0;
    for(U32 i = 0; i < list.size(); ++i)
    for(U32 i = 0; i < list.size(); ++i)
    {
    {
-      dStrcat( ret, list[i] );
-      dStrcat( ret, "\n" );
+      dStrcat( ret, list[i], size );
+      dStrcat( ret, "\n", size );
    }
    }
 
 
    return ret;
    return ret;
@@ -2709,8 +2709,8 @@ DefineConsoleMethod(TerrainEditor, getMaterials, const char *, (), , "() gets th
    ret[0] = 0;
    ret[0] = 0;
    for(U32 i = 0; i < terr->getMaterialCount(); i++)
    for(U32 i = 0; i < terr->getMaterialCount(); i++)
    {
    {
-      dStrcat( ret, terr->getMaterialName(i) );
-      dStrcat( ret, "\n" );
+      dStrcat( ret, terr->getMaterialName(i), 4096 );
+      dStrcat( ret, "\n", 4096 );
    }
    }
 
 
    return ret;
    return ret;

+ 5 - 5
Engine/source/materials/materialDefinition.cpp

@@ -661,28 +661,28 @@ DefineConsoleMethod( Material, getAnimFlags, const char*, (U32 id), , "" )
 	   if(dStrcmp( animFlags, "" ) == 0)
 	   if(dStrcmp( animFlags, "" ) == 0)
 	      dStrcpy( animFlags, "$Rotate" );
 	      dStrcpy( animFlags, "$Rotate" );
 	   else
 	   else
-			dStrcat( animFlags, " | $Rotate");
+			dStrcat( animFlags, " | $Rotate", 512);
    }
    }
    if(object->mAnimFlags[ id ] & Material::Wave)
    if(object->mAnimFlags[ id ] & Material::Wave)
    {
    {
 	   if(dStrcmp( animFlags, "" ) == 0)
 	   if(dStrcmp( animFlags, "" ) == 0)
 	      dStrcpy( animFlags, "$Wave" );
 	      dStrcpy( animFlags, "$Wave" );
 	   else
 	   else
-			dStrcat( animFlags, " | $Wave");
+			dStrcat( animFlags, " | $Wave", 512);
    }
    }
    if(object->mAnimFlags[ id ] & Material::Scale)
    if(object->mAnimFlags[ id ] & Material::Scale)
    {
    {
 	   if(dStrcmp( animFlags, "" ) == 0)
 	   if(dStrcmp( animFlags, "" ) == 0)
 	      dStrcpy( animFlags, "$Scale" );
 	      dStrcpy( animFlags, "$Scale" );
 	   else
 	   else
-			dStrcat( animFlags, " | $Scale");
+			dStrcat( animFlags, " | $Scale", 512);
    }
    }
    if(object->mAnimFlags[ id ] & Material::Sequence)
    if(object->mAnimFlags[ id ] & Material::Sequence)
    {
    {
 	   if(dStrcmp( animFlags, "" ) == 0)
 	   if(dStrcmp( animFlags, "" ) == 0)
 	      dStrcpy( animFlags, "$Sequence" );
 	      dStrcpy( animFlags, "$Sequence" );
 	   else
 	   else
-			dStrcat( animFlags, " | $Sequence");
+			dStrcat( animFlags, " | $Sequence", 512);
    }
    }
 
 
 	return animFlags;
 	return animFlags;
@@ -718,4 +718,4 @@ bool Material::_setAccuEnabled( void *object, const char *index, const char *dat
       AccumulationVolume::refreshVolumes();
       AccumulationVolume::refreshVolumes();
    }
    }
    return true;
    return true;
-}
+}

+ 2 - 2
Engine/source/platform/profiler.cpp

@@ -329,8 +329,8 @@ const char * Profiler::constructProfilePath(ProfilerData * pd)
       U32 mark = FrameAllocator::getWaterMark();
       U32 mark = FrameAllocator::getWaterMark();
       char * buf = (char*)FrameAllocator::alloc(len+1);
       char * buf = (char*)FrameAllocator::alloc(len+1);
       dStrcpy(buf,pd->mParent->mPath);
       dStrcpy(buf,pd->mParent->mPath);
-      dStrcat(buf,connector);
-      dStrcat(buf,pd->mRoot->mName);
+      dStrcat(buf,connector,len);
+      dStrcat(buf,pd->mRoot->mName,len);
       const char * ret = StringTable->insert(buf);
       const char * ret = StringTable->insert(buf);
       FrameAllocator::setWaterMark(mark);
       FrameAllocator::setWaterMark(mark);
       
       

+ 1 - 1
Engine/source/platformPOSIX/posixVolume.cpp

@@ -585,7 +585,7 @@ bool Platform::FS::InstallFileSystems()
    {
    {
       // add trailing '/' if it isn't there
       // add trailing '/' if it isn't there
       if (buffer[dStrlen(buffer) - 1] != '/')
       if (buffer[dStrlen(buffer) - 1] != '/')
-         dStrcat(buffer, "/");
+         dStrcat(buffer, "/", PATH_MAX);
          
          
       Platform::FS::SetCwd(buffer);
       Platform::FS::SetCwd(buffer);
    }
    }

+ 7 - 7
Engine/source/platformWin32/winDInputDevice.cpp

@@ -1552,25 +1552,25 @@ const char* DInputDevice::getJoystickAxesString()
       switch ( mObjInfo[i].mInst )
       switch ( mObjInfo[i].mInst )
       {
       {
          case SI_XAXIS:
          case SI_XAXIS:
-            dStrcat( buf, "\tX" );
+            dStrcat( buf, "\tX", 64 );
             break;
             break;
          case SI_YAXIS:
          case SI_YAXIS:
-            dStrcat( buf, "\tY" );
+            dStrcat( buf, "\tY", 64 );
             break;
             break;
          case SI_ZAXIS:
          case SI_ZAXIS:
-            dStrcat( buf, "\tZ" );
+            dStrcat( buf, "\tZ", 64 );
             break;
             break;
          case SI_RXAXIS:
          case SI_RXAXIS:
-            dStrcat( buf, "\tR" );
+            dStrcat( buf, "\tR", 64 );
             break;
             break;
          case SI_RYAXIS:
          case SI_RYAXIS:
-            dStrcat( buf, "\tU" );
+            dStrcat( buf, "\tU", 64 );
             break;
             break;
          case SI_RZAXIS:
          case SI_RZAXIS:
-            dStrcat( buf, "\tV" );
+            dStrcat( buf, "\tV", 64 );
             break;
             break;
          case SI_SLIDER:
          case SI_SLIDER:
-            dStrcat( buf, "\tS" );
+            dStrcat( buf, "\tS", 64 );
             break;
             break;
       }
       }
    }
    }

+ 5 - 4
Engine/source/platformWin32/winFileio.cpp

@@ -158,7 +158,8 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite)
 
 
       Platform::clearExcludedDirectories();
       Platform::clearExcludedDirectories();
 
 
-      TempAlloc< char > tempBuf( to.size * 3 + MAX_PATH * 3 );
+      S32 tempBufSize = to.size * 3 + MAX_PATH * 3;
+      TempAlloc< char > tempBuf( tempBufSize );
 
 
       // Create all the directories.
       // Create all the directories.
       for (S32 i = 0; i < directoryInfo.size(); i++)
       for (S32 i = 0; i < directoryInfo.size(); i++)
@@ -168,7 +169,7 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite)
          char* toDir = tempBuf;
          char* toDir = tempBuf;
          Platform::makeFullPathName(fromDir + dStrlen(fromName) + (dStricmp(fromDir, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
          Platform::makeFullPathName(fromDir + dStrlen(fromName) + (dStricmp(fromDir, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
          if(*(toDir + dStrlen(toDir) - 1) != '/')
          if(*(toDir + dStrlen(toDir) - 1) != '/')
-            dStrcat(toDir, "/");
+            dStrcat(toDir, "/", tempBufSize);
          forwardslash(toDir);
          forwardslash(toDir);
 
 
          if (!Platform::createPath(toDir))
          if (!Platform::createPath(toDir))
@@ -191,8 +192,8 @@ bool dPathCopy(const char *fromName, const char *toName, bool nooverwrite)
 
 
          char* toFile = tempBuf;
          char* toFile = tempBuf;
          Platform::makeFullPathName(fileInfo[i].pFullPath + dStrlen(fromName) + (dStricmp(fileInfo[i].pFullPath, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
          Platform::makeFullPathName(fileInfo[i].pFullPath + dStrlen(fromName) + (dStricmp(fileInfo[i].pFullPath, fromName) ? 1 : 0), tempBuf, tempBuf.size, toName);
-         dStrcat(toFile, "/");
-         dStrcat(toFile, fileInfo[i].pFileName);
+         dStrcat(toFile, "/", tempBufSize);
+         dStrcat(toFile, fileInfo[i].pFileName, tempBufSize);
 
 
          backslash(fromFile);
          backslash(fromFile);
          backslash(toFile);
          backslash(toFile);

+ 39 - 39
Engine/source/sim/actionMap.cpp

@@ -249,7 +249,7 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const
          iostrm->write( dStrlen( lineBuffer ), lineBuffer );
          iostrm->write( dStrlen( lineBuffer ), lineBuffer );
       }
       }
 
 
-      dSprintf(lineBuffer, 1023, "if (isObject(%s)) %s.delete();\n"
+      dSprintf(lineBuffer, 1024, "if (isObject(%s)) %s.delete();\n"
                                  "new ActionMap(%s);\n", getName(), getName(), getName());
                                  "new ActionMap(%s);\n", getName(), getName(), getName());
       iostrm->write(dStrlen(lineBuffer), lineBuffer);
       iostrm->write(dStrlen(lineBuffer), lineBuffer);
 
 
@@ -277,7 +277,7 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const
             else
             else
                command = "bind";
                command = "bind";
 
 
-            dSprintf(lineBuffer, 1023, "%s.%s(%s, \"%s%s\"",
+            dSprintf(lineBuffer, 1024, "%s.%s(%s, \"%s%s\"",
                                         getName(),
                                         getName(),
                                         command,
                                         command,
                                         devbuffer,
                                         devbuffer,
@@ -298,53 +298,53 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const
                   buff[curr++] = 'I';
                   buff[curr++] = 'I';
                buff[curr] = '\0';
                buff[curr] = '\0';
 
 
-               dStrcat(lineBuffer, buff);
+               dStrcat(lineBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::HasDeadZone) {
             if (rNode.flags & Node::HasDeadZone) {
                char buff[64];
                char buff[64];
                dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
                dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
-               dStrcat(lineBuffer, buff);
+               dStrcat(lineBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::HasScale) {
             if (rNode.flags & Node::HasScale) {
                char buff[64];
                char buff[64];
                dSprintf(buff, 63, ", %g", rNode.scaleFactor);
                dSprintf(buff, 63, ", %g", rNode.scaleFactor);
-               dStrcat(lineBuffer, buff);
+               dStrcat(lineBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::BindCmd) {
             if (rNode.flags & Node::BindCmd) {
                if (rNode.makeConsoleCommand) {
                if (rNode.makeConsoleCommand) {
-                  dStrcat(lineBuffer, ", \"");
+                  dStrcat(lineBuffer, ", \"", 1024);
                   U32 pos = dStrlen(lineBuffer);
                   U32 pos = dStrlen(lineBuffer);
                   expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
                   expandEscape(lineBuffer + pos, rNode.makeConsoleCommand);
-                  dStrcat(lineBuffer, "\"");
+                  dStrcat(lineBuffer, "\"", 1024);
                } else {
                } else {
-                  dStrcat(lineBuffer, ", \"\"");
+                  dStrcat(lineBuffer, ", \"\"", 1024);
                }
                }
                if (rNode.breakConsoleCommand) {
                if (rNode.breakConsoleCommand) {
-                  dStrcat(lineBuffer, ", \"");
+                  dStrcat(lineBuffer, ", \"", 1024);
                   U32 pos = dStrlen(lineBuffer);
                   U32 pos = dStrlen(lineBuffer);
                   expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
                   expandEscape(lineBuffer + pos, rNode.breakConsoleCommand);
-                  dStrcat(lineBuffer, "\"");
+                  dStrcat(lineBuffer, "\"", 1024);
                }
                }
                else
                else
-                  dStrcat(lineBuffer, ", \"\"");
+                  dStrcat(lineBuffer, ", \"\"", 1024);
             }
             }
             else if (rNode.flags & Node::Held) 
             else if (rNode.flags & Node::Held) 
             {
             {
-               dStrcat(lineBuffer, ", ");
-               dStrcat(lineBuffer, rNode.consoleFunction);
+               dStrcat(lineBuffer, ", ", 1024);
+               dStrcat(lineBuffer, rNode.consoleFunction, 1024);
 
 
-               dStrcat(lineBuffer, ", ");
-               dStrcat(lineBuffer, rNode.contextEvent->mConsoleFunctionHeld);
+               dStrcat(lineBuffer, ", ", 1024);
+               dStrcat(lineBuffer, rNode.contextEvent->mConsoleFunctionHeld, 1024);
             } 
             } 
             else {
             else {
-               dStrcat(lineBuffer, ", ");
-               dStrcat(lineBuffer, rNode.consoleFunction);
+               dStrcat(lineBuffer, ", ", 1024);
+               dStrcat(lineBuffer, rNode.consoleFunction, 1024);
             }
             }
 
 
-            dStrcat(lineBuffer, ");\n");
+            dStrcat(lineBuffer, ");\n", 1024);
             iostrm->write(dStrlen(lineBuffer), lineBuffer);
             iostrm->write(dStrlen(lineBuffer), lineBuffer);
          }
          }
       }
       }
@@ -377,7 +377,7 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const
                command = "bind";
                command = "bind";
 
 
             char finalBuffer[1024];
             char finalBuffer[1024];
-            dSprintf(finalBuffer, 1023, "%s.%s(%s, \"%s%s\"",
+            dSprintf(finalBuffer, 1024, "%s.%s(%s, \"%s%s\"",
                                         getName(),
                                         getName(),
                                         command,
                                         command,
                                         devbuffer,
                                         devbuffer,
@@ -398,51 +398,51 @@ void ActionMap::dumpActionMap(const char* fileName, const bool append) const
                   buff[curr++] = 'I';
                   buff[curr++] = 'I';
                buff[curr] = '\0';
                buff[curr] = '\0';
 
 
-               dStrcat(finalBuffer, buff);
+               dStrcat(finalBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::HasDeadZone) {
             if (rNode.flags & Node::HasDeadZone) {
                char buff[64];
                char buff[64];
                dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
                dSprintf(buff, 63, ", \"%g %g\"", rNode.deadZoneBegin, rNode.deadZoneEnd);
-               dStrcat(finalBuffer, buff);
+               dStrcat(finalBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::HasScale) {
             if (rNode.flags & Node::HasScale) {
                char buff[64];
                char buff[64];
                dSprintf(buff, 63, ", %g", rNode.scaleFactor);
                dSprintf(buff, 63, ", %g", rNode.scaleFactor);
-               dStrcat(finalBuffer, buff);
+               dStrcat(finalBuffer, buff, 1024);
             }
             }
 
 
             if (rNode.flags & Node::BindCmd) {
             if (rNode.flags & Node::BindCmd) {
                if (rNode.makeConsoleCommand) {
                if (rNode.makeConsoleCommand) {
-                  dStrcat(finalBuffer, ", \"");
-                  dStrcat(finalBuffer, rNode.makeConsoleCommand);
-                  dStrcat(finalBuffer, "\"");
+                  dStrcat(finalBuffer, ", \"", 1024);
+                  dStrcat(finalBuffer, rNode.makeConsoleCommand, 1024);
+                  dStrcat(finalBuffer, "\"", 1024);
                } else {
                } else {
-                  dStrcat(finalBuffer, ", \"\"");
+                  dStrcat(finalBuffer, ", \"\"", 1024);
                }
                }
                if (rNode.breakConsoleCommand) {
                if (rNode.breakConsoleCommand) {
-                  dStrcat(finalBuffer, ", \"");
-                  dStrcat(finalBuffer, rNode.breakConsoleCommand);
-                  dStrcat(finalBuffer, "\"");
+                  dStrcat(finalBuffer, ", \"", 1024);
+                  dStrcat(finalBuffer, rNode.breakConsoleCommand, 1024);
+                  dStrcat(finalBuffer, "\"", 1024);
                }
                }
                else
                else
-                  dStrcat(finalBuffer, ", \"\"");
+                  dStrcat(finalBuffer, ", \"\"", 1024);
             }
             }
             else if (rNode.flags & Node::Held)
             else if (rNode.flags & Node::Held)
             {
             {
-               dStrcat(finalBuffer, ", ");
-               dStrcat(finalBuffer, rNode.consoleFunction);
+               dStrcat(finalBuffer, ", ", 1024);
+               dStrcat(finalBuffer, rNode.consoleFunction, 1024);
 
 
-               dStrcat(finalBuffer, ", ");
-               dStrcat(finalBuffer, rNode.contextEvent->mConsoleFunctionHeld);
+               dStrcat(finalBuffer, ", ", 1024);
+               dStrcat(finalBuffer, rNode.contextEvent->mConsoleFunctionHeld, 1024);
             } 
             } 
             else {
             else {
-               dStrcat(finalBuffer, ", ");
-               dStrcat(finalBuffer, rNode.consoleFunction);
+               dStrcat(finalBuffer, ", ", 1024);
+               dStrcat(finalBuffer, rNode.consoleFunction, 1024);
             }
             }
 
 
-            dStrcat(finalBuffer, ");");
+            dStrcat(finalBuffer, ");", 1024);
             Con::printf(finalBuffer);
             Con::printf(finalBuffer);
          }
          }
       }
       }
@@ -786,8 +786,8 @@ const char* ActionMap::getBinding( const char* command )
          {
          {
             dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
             dSprintf( buffer, sizeof( buffer ), "%s\t%s%s", deviceBuffer, modifierString, keyBuffer );
             if ( returnString[0] )
             if ( returnString[0] )
-               dStrcat( returnString, "\t" );
-            dStrcat( returnString, buffer );
+               dStrcat( returnString, "\t", 1024 );
+            dStrcat( returnString, buffer, 1024 );
          }
          }
       }
       }
 
 

+ 1 - 1
Engine/source/sim/netStringTable.cpp

@@ -239,7 +239,7 @@ void NetStringTable::expandString(NetStringHandle &inString, char *buf, U32 bufS
       }
       }
       buf[bufSize - 1] = 0;
       buf[bufSize - 1] = 0;
    } else {
    } else {
-      dStrcat(buf, "<NULL>");
+      dStrcat(buf, "<NULL>", bufSize);
    }
    }
 }
 }
 
 

+ 2 - 2
Engine/source/terrain/terrData.cpp

@@ -1306,7 +1306,7 @@ DefineEngineMethod( TerrainBlock, save, bool, ( const char* fileName),,
 	dStrcpy(filename,fileName);
 	dStrcpy(filename,fileName);
    char *ext = dStrrchr(filename, '.');
    char *ext = dStrrchr(filename, '.');
    if (!ext || dStricmp(ext, ".ter") != 0)
    if (!ext || dStricmp(ext, ".ter") != 0)
-      dStrcat(filename, ".ter");
+      dStrcat(filename, ".ter", 256);
    return static_cast<TerrainBlock*>(object)->save(filename);
    return static_cast<TerrainBlock*>(object)->save(filename);
 }
 }
 
 
@@ -1316,7 +1316,7 @@ DefineEngineMethod( TerrainBlock, save, bool, ( const char* fileName),,
 //   dStrcpy(filename,argv[2]);
 //   dStrcpy(filename,argv[2]);
 //   char *ext = dStrrchr(filename, '.');
 //   char *ext = dStrrchr(filename, '.');
 //   if (!ext || dStricmp(ext, ".ter") != 0)
 //   if (!ext || dStricmp(ext, ".ter") != 0)
-//      dStrcat(filename, ".ter");
+//      dStrcat(filename, ".ter", 256);
 //   return static_cast<TerrainBlock*>(object)->save(filename);
 //   return static_cast<TerrainBlock*>(object)->save(filename);
 //}
 //}