Переглянути джерело

added security fix in array.sort() when cmp function resizes the array

albertodemichelis 5 роки тому
батько
коміт
7dd0153f10
1 змінених файлів з 10 додано та 4 видалено
  1. 10 4
      squirrel/sqbaselib.cpp

+ 10 - 4
squirrel/sqbaselib.cpp

@@ -754,7 +754,7 @@ static SQInteger array_find(HSQUIRRELVM v)
 }
 
 
-static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
+static bool _sort_compare(HSQUIRRELVM v, SQArray *arr, SQObjectPtr &a,SQObjectPtr &b,SQInteger func,SQInteger &ret)
 {
     if(func < 0) {
         if(!v->ObjCmp(a,b,ret)) return false;
@@ -765,15 +765,21 @@ static bool _sort_compare(HSQUIRRELVM v,SQObjectPtr &a,SQObjectPtr &b,SQInteger
         sq_pushroottable(v);
         v->Push(a);
         v->Push(b);
+		SQObjectPtr *valptr = arr->_values._vals;
+		SQUnsignedInteger precallsize = arr->_values.size();
         if(SQ_FAILED(sq_call(v, 3, SQTrue, SQFalse))) {
             if(!sq_isstring( v->_lasterror))
                 v->Raise_Error(_SC("compare func failed"));
             return false;
         }
-        if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
+		if(SQ_FAILED(sq_getinteger(v, -1, &ret))) {
             v->Raise_Error(_SC("numeric value expected as return value of the compare function"));
             return false;
         }
+		if (precallsize != arr->_values.size() || valptr != arr->_values._vals) {
+			v->Raise_Error(_SC("array resized during sort operation"));
+			return false;
+		}
         sq_settop(v, top);
         return true;
     }
@@ -792,7 +798,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg
             maxChild = root2;
         }
         else {
-            if(!_sort_compare(v,arr->_values[root2],arr->_values[root2 + 1],func,ret))
+            if(!_sort_compare(v,arr,arr->_values[root2],arr->_values[root2 + 1],func,ret))
                 return false;
             if (ret > 0) {
                 maxChild = root2;
@@ -802,7 +808,7 @@ static bool _hsort_sift_down(HSQUIRRELVM v,SQArray *arr, SQInteger root, SQInteg
             }
         }
 
-        if(!_sort_compare(v,arr->_values[root],arr->_values[maxChild],func,ret))
+        if(!_sort_compare(v,arr,arr->_values[root],arr->_values[maxChild],func,ret))
             return false;
         if (ret < 0) {
             if (root == maxChild) {