@@ -327,7 +327,16 @@ namespace SQVector
327327 }
328328
329329 SQUserPointer p;
330- sq_getinstanceup (vm, 1 , &p, 0 );
330+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , &p, 0 )))
331+ {
332+ return SQ_ERROR;
333+ }
334+
335+ if (!p)
336+ {
337+ return sq_throwerror (vm, " Accessed null instance" );
338+ }
339+
331340 new (p) Vector (x, y, z);
332341
333342 return 0 ;
@@ -343,7 +352,7 @@ namespace SQVector
343352 return sq_throwerror (vm, " Expected Vector._get(string)" );
344353 }
345354
346- if (key[0 ] < ' x' || key[' 0 ' ] > ' z' || key[1 ] != ' \0 ' )
355+ if (key[0 ] < ' x' || key[0 ] > ' z' || key[1 ] != ' \0 ' )
347356 {
348357 return sqstd_throwerrorf (vm, " the index '%.50s' does not exist" , key);
349358 }
@@ -369,7 +378,7 @@ namespace SQVector
369378 return sq_throwerror (vm, " Expected Vector._set(string)" );
370379 }
371380
372- if (key[0 ] < ' x' || key[' 0 ' ] > ' z' || key[1 ] != ' \0 ' )
381+ if (key[0 ] < ' x' || key[0 ] > ' z' || key[1 ] != ' \0 ' )
373382 {
374383 return sqstd_throwerrorf (vm, " the index '%.50s' does not exist" , key);
375384 }
@@ -1291,10 +1300,7 @@ bool getVariant(HSQUIRRELVM vm, SQInteger idx, ScriptVariant_t& variant)
12911300 case OT_INSTANCE:
12921301 {
12931302 Vector* v = nullptr ;
1294- SQUserPointer tag;
1295- if (SQ_SUCCEEDED (sq_gettypetag (vm, idx, &tag)) &&
1296- tag == TYPETAG_VECTOR &&
1297- SQ_SUCCEEDED (sq_getinstanceup (vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
1303+ if (SQ_SUCCEEDED (sq_getinstanceup (vm, idx, (SQUserPointer*)&v, TYPETAG_VECTOR)))
12981304 {
12991305 variant.Free ();
13001306 variant = (Vector*)malloc (sizeof (Vector));
@@ -1323,12 +1329,10 @@ SQInteger function_stub(HSQUIRRELVM vm)
13231329{
13241330 SQInteger top = sq_gettop (vm);
13251331
1326- SQUserPointer userptr = nullptr ;
1327- sq_getuserpointer (vm, top, &userptr);
1328-
1329- Assert (userptr);
1332+ ScriptFunctionBinding_t* pFunc = nullptr ;
1333+ sq_getuserpointer (vm, top, (SQUserPointer*)&pFunc);
13301334
1331- ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr ;
1335+ Assert (pFunc) ;
13321336
13331337 int nargs = pFunc->m_desc .m_Parameters .Count ();
13341338 int nLastHScriptIdx = -1 ;
@@ -1424,15 +1428,30 @@ SQInteger function_stub(HSQUIRRELVM vm)
14241428
14251429 if (pFunc->m_flags & SF_MEMBER_FUNC)
14261430 {
1427- SQUserPointer self;
1428- sq_getinstanceup (vm, 1 , &self, nullptr );
1431+ ClassInstanceData* classInstanceData;
1432+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 )))
1433+ {
1434+ return SQ_ERROR;
1435+ }
14291436
1430- if (!self )
1437+ if (!classInstanceData )
14311438 {
14321439 return sq_throwerror (vm, " Accessed null instance" );
14331440 }
14341441
1435- instance = ((ClassInstanceData*)self)->instance ;
1442+ // check that the type of self, or any basetype, matches the function description
1443+ ScriptClassDesc_t *selfType = classInstanceData->desc ;
1444+ while (selfType != pFunc->m_desc .m_pScriptClassDesc )
1445+ {
1446+ if (!selfType)
1447+ {
1448+ return sq_throwerror (vm, " Mismatched instance type" );
1449+ }
1450+ selfType = selfType->m_pBaseDesc ;
1451+ Assert (selfType != classInstanceData->desc ); // there should be no infinite loop
1452+ }
1453+
1454+ instance = classInstanceData->instance ;
14361455 }
14371456
14381457 ScriptVariant_t script_retval;
@@ -1441,8 +1460,6 @@ SQInteger function_stub(HSQUIRRELVM vm)
14411460 SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr (vm);
14421461 Assert (pSquirrelVM);
14431462
1444- sq_resetobject (&pSquirrelVM->lastError_ );
1445-
14461463 bool call_success = (*pFunc->m_pfnBinding )(pFunc->m_pFunction , instance, params.Base (), nargs,
14471464 pFunc->m_desc .m_ReturnType == FIELD_VOID ? nullptr : &script_retval, script_retval_storage);
14481465 Assert (call_success);
@@ -1452,6 +1469,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
14521469 if (!sq_isnull (pSquirrelVM->lastError_ ))
14531470 {
14541471 sq_pushobject (vm, pSquirrelVM->lastError_ );
1472+ sq_release (vm, &pSquirrelVM->lastError_ );
14551473 sq_resetobject (&pSquirrelVM->lastError_ );
14561474 sq_retval = sq_throwobject (vm);
14571475 }
@@ -1521,28 +1539,42 @@ SQInteger destructor_stub_instance(SQUserPointer p, SQInteger size)
15211539SQInteger constructor_stub (HSQUIRRELVM vm)
15221540{
15231541 ScriptClassDesc_t* pClassDesc = nullptr ;
1524- sq_gettypetag (vm, 1 , (SQUserPointer*)&pClassDesc);
1542+ if (SQ_FAILED (sq_gettypetag (vm, 1 , (SQUserPointer*)&pClassDesc)))
1543+ {
1544+ return sq_throwerror (vm, " Expected native class" );
1545+ }
1546+
1547+ if (!pClassDesc || (void *)pClassDesc == TYPETAG_VECTOR)
1548+ {
1549+ return sq_throwerror (vm, " Unable to obtain native class description" );
1550+ }
15251551
15261552 if (!pClassDesc->m_pfnConstruct )
15271553 {
15281554 return sqstd_throwerrorf (vm, " Unable to construct instances of %s" , pClassDesc->m_pszScriptName );
15291555 }
15301556
1531- SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr (vm);
1532- Assert (pSquirrelVM);
1557+ SQUserPointer p;
1558+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , &p, 0 )))
1559+ {
1560+ return SQ_ERROR;
1561+ }
15331562
1534- sq_resetobject (&pSquirrelVM->lastError_ );
1563+ if (!p)
1564+ {
1565+ return sq_throwerror (vm, " Accessed null instance" );
1566+ }
15351567
15361568 void * instance = pClassDesc->m_pfnConstruct ();
15371569
1570+ #ifdef DBGFLAG_ASSERT
1571+ SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr (vm);
1572+ Assert (pSquirrelVM);
15381573 // expect construction to always succeed
15391574 Assert (sq_isnull (pSquirrelVM->lastError_ ));
1575+ #endif
15401576
1541- {
1542- SQUserPointer p;
1543- sq_getinstanceup (vm, 1 , &p, 0 );
1544- new (p) ClassInstanceData (instance, pClassDesc, nullptr , true );
1545- }
1577+ new (p) ClassInstanceData (instance, pClassDesc, nullptr , true );
15461578
15471579 sq_setreleasehook (vm, 1 , &destructor_stub);
15481580
@@ -1552,7 +1584,10 @@ SQInteger constructor_stub(HSQUIRRELVM vm)
15521584SQInteger tostring_stub (HSQUIRRELVM vm)
15531585{
15541586 ClassInstanceData* classInstanceData = nullptr ;
1555- sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 );
1587+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 )))
1588+ {
1589+ return SQ_ERROR;
1590+ }
15561591
15571592 char buffer[128 ] = " " ;
15581593
@@ -1582,7 +1617,10 @@ SQInteger tostring_stub(HSQUIRRELVM vm)
15821617SQInteger get_stub (HSQUIRRELVM vm)
15831618{
15841619 ClassInstanceData* classInstanceData = nullptr ;
1585- sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 );
1620+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 )))
1621+ {
1622+ return SQ_ERROR;
1623+ }
15861624
15871625 const char * key = nullptr ;
15881626 sq_getstring (vm, 2 , &key);
@@ -1614,7 +1652,10 @@ SQInteger get_stub(HSQUIRRELVM vm)
16141652SQInteger set_stub (HSQUIRRELVM vm)
16151653{
16161654 ClassInstanceData* classInstanceData = nullptr ;
1617- sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 );
1655+ if (SQ_FAILED (sq_getinstanceup (vm, 1 , (SQUserPointer*)&classInstanceData, 0 )))
1656+ {
1657+ return SQ_ERROR;
1658+ }
16181659
16191660 const char * key = nullptr ;
16201661 sq_getstring (vm, 2 , &key);
@@ -2710,10 +2751,8 @@ void SquirrelVM::SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId)
27102751 HSQOBJECT* obj = (HSQOBJECT*)hInstance;
27112752 sq_pushobject (vm_, *obj);
27122753
2713- SQUserPointer self;
2714- sq_getinstanceup (vm_, -1 , &self, nullptr );
2715-
2716- auto classInstanceData = (ClassInstanceData*)self;
2754+ ClassInstanceData* classInstanceData;
2755+ sq_getinstanceup (vm_, -1 , (SQUserPointer*)&classInstanceData, nullptr );
27172756
27182757 classInstanceData->instanceId = pszId;
27192758
@@ -2771,11 +2810,10 @@ void* SquirrelVM::GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpect
27712810 }
27722811
27732812 sq_pushobject (vm_, *obj);
2774- SQUserPointer self ;
2775- sq_getinstanceup (vm_, -1 , &self , nullptr );
2813+ ClassInstanceData* classInstanceData ;
2814+ sq_getinstanceup (vm_, -1 , (SQUserPointer*)&classInstanceData , nullptr );
27762815 sq_pop (vm_, 1 );
27772816
2778- auto classInstanceData = (ClassInstanceData*)self;
27792817
27802818 if (!classInstanceData)
27812819 {
0 commit comments