Pārlūkot izejas kodu

Fix issue with registered variables becoming corrupted when string value was accessed.

James Urquhart 10 gadi atpakaļ
vecāks
revīzija
15169eab9f

+ 13 - 8
Engine/source/console/console.cpp

@@ -1769,7 +1769,7 @@ const char *ConsoleValue::getStringValue()
       else if(type == TypeInternalInt)
       else if(type == TypeInternalInt)
          internalValue = Con::getData(TypeS32, &ival, 0);
          internalValue = Con::getData(TypeS32, &ival, 0);
       else
       else
-         internalValue = Con::getData(type, dataPtr, 0, enumTable);
+         return Con::getData(type, dataPtr, 0, enumTable); // We can't save sval here since it is the same as dataPtr
 
 
       if (!internalValue)
       if (!internalValue)
          return "";
          return "";
@@ -1777,12 +1777,14 @@ const char *ConsoleValue::getStringValue()
       U32 stringLen = dStrlen(internalValue);
       U32 stringLen = dStrlen(internalValue);
       U32 newLen = ((stringLen + 1) + 15) & ~15; // pad upto next cache line
       U32 newLen = ((stringLen + 1) + 15) & ~15; // pad upto next cache line
 	   
 	   
-      if(sval == typeValueEmpty || type == TypeInternalStackString || type == TypeInternalStringStackPtr)
+      if (bufferLen == 0)
          sval = (char *) dMalloc(newLen);
          sval = (char *) dMalloc(newLen);
       else if(newLen > bufferLen)
       else if(newLen > bufferLen)
          sval = (char *) dRealloc(sval, newLen);
          sval = (char *) dRealloc(sval, newLen);
 
 
       dStrcpy(sval, internalValue);
       dStrcpy(sval, internalValue);
+      bufferLen = newLen;
+
       return sval;
       return sval;
    }
    }
 }
 }
@@ -1820,11 +1822,13 @@ void ConsoleValue::setIntValue(U32 val)
    {
    {
       fval = (F32)val;
       fval = (F32)val;
       ival = val;
       ival = val;
-      if(sval != typeValueEmpty)
+      if(bufferLen > 0)
       {
       {
-         if (type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-         sval = typeValueEmpty;
+         dFree(sval);
+         bufferLen = 0;
       }
       }
+
+      sval = typeValueEmpty;
       type = TypeInternalInt;
       type = TypeInternalInt;
    }
    }
    else
    else
@@ -1845,11 +1849,12 @@ void ConsoleValue::setFloatValue(F32 val)
    {
    {
       fval = val;
       fval = val;
       ival = static_cast<U32>(val);
       ival = static_cast<U32>(val);
-      if(sval != typeValueEmpty)
+      if(bufferLen > 0)
       {
       {
-         if (type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-         sval = typeValueEmpty;
+         dFree(sval);
+         bufferLen = 0;
       }
       }
+      sval = typeValueEmpty;
       type = TypeInternalFloat;
       type = TypeInternalFloat;
    }
    }
    else
    else

+ 5 - 4
Engine/source/console/console.h

@@ -186,19 +186,20 @@ public:
       fval = 0;
       fval = 0;
       sval = typeValueEmpty;
       sval = typeValueEmpty;
       bufferLen = 0;
       bufferLen = 0;
-	  type = TypeInternalString;
+      type = TypeInternalString;
    }
    }
    
    
    void cleanup()
    void cleanup()
    {
    {
-      if (type <= TypeInternalString &&
-          sval != typeValueEmpty && type != TypeInternalStackString && type != TypeInternalStringStackPtr)
+      if (bufferLen > 0)
+      {
          dFree(sval);
          dFree(sval);
+         bufferLen = 0;
+      }
       sval = typeValueEmpty;
       sval = typeValueEmpty;
       type = ConsoleValue::TypeInternalString;
       type = ConsoleValue::TypeInternalString;
       ival = 0;
       ival = 0;
       fval = 0;
       fval = 0;
-      bufferLen = 0;
    }
    }
 };
 };
 
 

+ 25 - 12
Engine/source/console/consoleInternal.cpp

@@ -512,13 +512,17 @@ void ConsoleValue::setStringValue(const char * value)
 */
 */
 	   if (value == typeValueEmpty)
 	   if (value == typeValueEmpty)
       {
       {
-            if (sval && sval != typeValueEmpty && type != TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
-            sval = typeValueEmpty;
+         if (bufferLen > 0)
+         {
+            dFree(sval);
             bufferLen = 0;
             bufferLen = 0;
-            fval = 0.f;
-            ival = 0;
-            type = TypeInternalString;
-            return;
+         }
+
+         sval = typeValueEmpty;
+         fval = 0.f;
+         ival = 0;
+         type = TypeInternalString;
+         return;
       }
       }
 
 
       U32 stringLen = dStrlen(value);
       U32 stringLen = dStrlen(value);
@@ -541,7 +545,7 @@ void ConsoleValue::setStringValue(const char * value)
       // may as well pad to the next cache line
       // may as well pad to the next cache line
       U32 newLen = ((stringLen + 1) + 15) & ~15;
       U32 newLen = ((stringLen + 1) + 15) & ~15;
 	  
 	  
-      if(sval == typeValueEmpty || type == TypeInternalStackString || type == TypeInternalStringStackPtr)
+      if(bufferLen == 0)
          sval = (char *) dMalloc(newLen);
          sval = (char *) dMalloc(newLen);
       else if(newLen > bufferLen)
       else if(newLen > bufferLen)
          sval = (char *) dRealloc(sval, newLen);
          sval = (char *) dRealloc(sval, newLen);
@@ -562,11 +566,16 @@ void ConsoleValue::setStackStringValue(const char *value)
 
 
    if(type <= ConsoleValue::TypeInternalString)
    if(type <= ConsoleValue::TypeInternalString)
    {
    {
+      // sval might still be temporarily present so we need to check and free it
+      if (bufferLen > 0)
+      {
+         dFree(sval);
+         bufferLen = 0;
+      }
+
 	   if (value == typeValueEmpty)
 	   if (value == typeValueEmpty)
       {
       {
-         if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString && type != ConsoleValue::TypeInternalStringStackPtr) dFree(sval);
          sval = typeValueEmpty;
          sval = typeValueEmpty;
-         bufferLen = 0;
          fval = 0.f;
          fval = 0.f;
          ival = 0;
          ival = 0;
          type = TypeInternalString;
          type = TypeInternalString;
@@ -587,7 +596,7 @@ void ConsoleValue::setStackStringValue(const char *value)
 
 
       type = TypeInternalStackString;
       type = TypeInternalStackString;
       sval = (char*)value;
       sval = (char*)value;
-      bufferLen = stringLen;
+      bufferLen = 0;
    }
    }
    else
    else
       Con::setData(type, dataPtr, 0, 1, &value, enumTable);      
       Con::setData(type, dataPtr, 0, 1, &value, enumTable);      
@@ -598,7 +607,11 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
    if(type <= ConsoleValue::TypeInternalString)
    if(type <= ConsoleValue::TypeInternalString)
    {
    {
       const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
       const char *value = StringStackPtrRef(ptrValue).getPtr(&STR);
-	   if (sval && sval != typeValueEmpty && type != ConsoleValue::TypeInternalStackString && type != TypeInternalStringStackPtr) dFree(sval);
+	   if (bufferLen > 0)
+      {
+         dFree(sval);
+         bufferLen = 0;
+      }
 
 
       U32 stringLen = dStrlen(value);
       U32 stringLen = dStrlen(value);
       if(stringLen < 256)
       if(stringLen < 256)
@@ -614,7 +627,7 @@ void ConsoleValue::setStringStackPtrValue(StringStackPtr ptrValue)
 
 
       type = TypeInternalStringStackPtr;
       type = TypeInternalStringStackPtr;
       sval = (char*)(value - STR.mBuffer);
       sval = (char*)(value - STR.mBuffer);
-      bufferLen = stringLen;
+      bufferLen = 0;
    }
    }
    else
    else
    {
    {