@@ -327,7 +327,16 @@ namespace SQVector
327
327
}
328
328
329
329
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
+
331
340
new (p) Vector (x, y, z);
332
341
333
342
return 0 ;
@@ -343,7 +352,7 @@ namespace SQVector
343
352
return sq_throwerror (vm, " Expected Vector._get(string)" );
344
353
}
345
354
346
- if (key[0 ] < ' x' || key[' 0 ' ] > ' z' || key[1 ] != ' \0 ' )
355
+ if (key[0 ] < ' x' || key[0 ] > ' z' || key[1 ] != ' \0 ' )
347
356
{
348
357
return sqstd_throwerrorf (vm, " the index '%.50s' does not exist" , key);
349
358
}
@@ -369,7 +378,7 @@ namespace SQVector
369
378
return sq_throwerror (vm, " Expected Vector._set(string)" );
370
379
}
371
380
372
- if (key[0 ] < ' x' || key[' 0 ' ] > ' z' || key[1 ] != ' \0 ' )
381
+ if (key[0 ] < ' x' || key[0 ] > ' z' || key[1 ] != ' \0 ' )
373
382
{
374
383
return sqstd_throwerrorf (vm, " the index '%.50s' does not exist" , key);
375
384
}
@@ -1291,10 +1300,7 @@ bool getVariant(HSQUIRRELVM vm, SQInteger idx, ScriptVariant_t& variant)
1291
1300
case OT_INSTANCE:
1292
1301
{
1293
1302
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)))
1298
1304
{
1299
1305
variant.Free ();
1300
1306
variant = (Vector*)malloc (sizeof (Vector));
@@ -1323,12 +1329,10 @@ SQInteger function_stub(HSQUIRRELVM vm)
1323
1329
{
1324
1330
SQInteger top = sq_gettop (vm);
1325
1331
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);
1330
1334
1331
- ScriptFunctionBinding_t* pFunc = (ScriptFunctionBinding_t*)userptr ;
1335
+ Assert (pFunc) ;
1332
1336
1333
1337
int nargs = pFunc->m_desc .m_Parameters .Count ();
1334
1338
int nLastHScriptIdx = -1 ;
@@ -1424,15 +1428,30 @@ SQInteger function_stub(HSQUIRRELVM vm)
1424
1428
1425
1429
if (pFunc->m_flags & SF_MEMBER_FUNC)
1426
1430
{
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
+ }
1429
1436
1430
- if (!self )
1437
+ if (!classInstanceData )
1431
1438
{
1432
1439
return sq_throwerror (vm, " Accessed null instance" );
1433
1440
}
1434
1441
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 ;
1436
1455
}
1437
1456
1438
1457
ScriptVariant_t script_retval;
@@ -1441,8 +1460,6 @@ SQInteger function_stub(HSQUIRRELVM vm)
1441
1460
SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr (vm);
1442
1461
Assert (pSquirrelVM);
1443
1462
1444
- sq_resetobject (&pSquirrelVM->lastError_ );
1445
-
1446
1463
bool call_success = (*pFunc->m_pfnBinding )(pFunc->m_pFunction , instance, params.Base (), nargs,
1447
1464
pFunc->m_desc .m_ReturnType == FIELD_VOID ? nullptr : &script_retval, script_retval_storage);
1448
1465
Assert (call_success);
@@ -1452,6 +1469,7 @@ SQInteger function_stub(HSQUIRRELVM vm)
1452
1469
if (!sq_isnull (pSquirrelVM->lastError_ ))
1453
1470
{
1454
1471
sq_pushobject (vm, pSquirrelVM->lastError_ );
1472
+ sq_release (vm, &pSquirrelVM->lastError_ );
1455
1473
sq_resetobject (&pSquirrelVM->lastError_ );
1456
1474
sq_retval = sq_throwobject (vm);
1457
1475
}
@@ -1521,28 +1539,42 @@ SQInteger destructor_stub_instance(SQUserPointer p, SQInteger size)
1521
1539
SQInteger constructor_stub (HSQUIRRELVM vm)
1522
1540
{
1523
1541
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
+ }
1525
1551
1526
1552
if (!pClassDesc->m_pfnConstruct )
1527
1553
{
1528
1554
return sqstd_throwerrorf (vm, " Unable to construct instances of %s" , pClassDesc->m_pszScriptName );
1529
1555
}
1530
1556
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
+ }
1533
1562
1534
- sq_resetobject (&pSquirrelVM->lastError_ );
1563
+ if (!p)
1564
+ {
1565
+ return sq_throwerror (vm, " Accessed null instance" );
1566
+ }
1535
1567
1536
1568
void * instance = pClassDesc->m_pfnConstruct ();
1537
1569
1570
+ #ifdef DBGFLAG_ASSERT
1571
+ SquirrelVM* pSquirrelVM = (SquirrelVM*)sq_getsharedforeignptr (vm);
1572
+ Assert (pSquirrelVM);
1538
1573
// expect construction to always succeed
1539
1574
Assert (sq_isnull (pSquirrelVM->lastError_ ));
1575
+ #endif
1540
1576
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 );
1546
1578
1547
1579
sq_setreleasehook (vm, 1 , &destructor_stub);
1548
1580
@@ -1552,7 +1584,10 @@ SQInteger constructor_stub(HSQUIRRELVM vm)
1552
1584
SQInteger tostring_stub (HSQUIRRELVM vm)
1553
1585
{
1554
1586
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
+ }
1556
1591
1557
1592
char buffer[128 ] = " " ;
1558
1593
@@ -1582,7 +1617,10 @@ SQInteger tostring_stub(HSQUIRRELVM vm)
1582
1617
SQInteger get_stub (HSQUIRRELVM vm)
1583
1618
{
1584
1619
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
+ }
1586
1624
1587
1625
const char * key = nullptr ;
1588
1626
sq_getstring (vm, 2 , &key);
@@ -1614,7 +1652,10 @@ SQInteger get_stub(HSQUIRRELVM vm)
1614
1652
SQInteger set_stub (HSQUIRRELVM vm)
1615
1653
{
1616
1654
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
+ }
1618
1659
1619
1660
const char * key = nullptr ;
1620
1661
sq_getstring (vm, 2 , &key);
@@ -2710,10 +2751,8 @@ void SquirrelVM::SetInstanceUniqeId(HSCRIPT hInstance, const char* pszId)
2710
2751
HSQOBJECT* obj = (HSQOBJECT*)hInstance;
2711
2752
sq_pushobject (vm_, *obj);
2712
2753
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 );
2717
2756
2718
2757
classInstanceData->instanceId = pszId;
2719
2758
@@ -2771,11 +2810,10 @@ void* SquirrelVM::GetInstanceValue(HSCRIPT hInstance, ScriptClassDesc_t* pExpect
2771
2810
}
2772
2811
2773
2812
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 );
2776
2815
sq_pop (vm_, 1 );
2777
2816
2778
- auto classInstanceData = (ClassInstanceData*)self;
2779
2817
2780
2818
if (!classInstanceData)
2781
2819
{
0 commit comments