diff options
author | Benoit Germain <bnt.germain@gmail.com> | 2013-11-04 11:27:04 +0100 |
---|---|---|
committer | Benoit Germain <bnt.germain@gmail.com> | 2013-11-04 11:27:04 +0100 |
commit | 39243fa43e43c15613c7f2dd9de8de6ab4daaa4e (patch) | |
tree | b4f391a877c15b9c30c1264ba9462db91e5a8102 /src | |
parent | 41864c0725ec5e9c929911fd8f41c34c4cbacf27 (diff) | |
download | lanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.tar.gz lanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.tar.bz2 lanes-39243fa43e43c15613c7f2dd9de8de6ab4daaa4e.zip |
Fix lanes.nameof() crashing when encountering a light userdata
Diffstat (limited to 'src')
-rw-r--r-- | src/tools.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/src/tools.c b/src/tools.c index 95104d6..f445068 100644 --- a/src/tools.c +++ b/src/tools.c | |||
@@ -1359,12 +1359,12 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1359 | lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1 | 1359 | lua_pushinteger( L, 1); // o "r" {c} {fqn} ... {?} {?} 1 |
1360 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} | 1360 | lua_rawset( L, cache); // o "r" {c} {fqn} ... {?} |
1361 | // scan table contents | 1361 | // scan table contents |
1362 | STACK_CHECK( L); | ||
1363 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil | 1362 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} nil |
1364 | while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v | 1363 | while( lua_next( L, -2)) // o "r" {c} {fqn} ... {?} k v |
1365 | { | 1364 | { |
1366 | //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : NULL; // only for debugging | 1365 | //char const *const strKey = (lua_type( L, -2) == LUA_TSTRING) ? lua_tostring( L, -2) : NULL; // only for debugging |
1367 | //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging | 1366 | //lua_Number const numKey = (lua_type( L, -2) == LUA_TNUMBER) ? lua_tonumber( L, -2) : -6666; // only for debugging |
1367 | STACK_MID( L, 2); | ||
1368 | // append key name to fqn stack | 1368 | // append key name to fqn stack |
1369 | ++ depth_; | 1369 | ++ depth_; |
1370 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k | 1370 | lua_pushvalue( L, -2); // o "r" {c} {fqn} ... {?} k v k |
@@ -1384,8 +1384,12 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1384 | STACK_MID( L, 0); | 1384 | STACK_MID( L, 0); |
1385 | break; | 1385 | break; |
1386 | } | 1386 | } |
1387 | else if( lua_istable( L, -1)) // o "r" {c} {fqn} ... {?} k {} | 1387 | switch( lua_type( L, -1)) // o "r" {c} {fqn} ... {?} k v |
1388 | { | 1388 | { |
1389 | default: // nil, boolean, light userdata, number and string aren't identifiable | ||
1390 | break; | ||
1391 | |||
1392 | case LUA_TTABLE: // o "r" {c} {fqn} ... {?} k {} | ||
1389 | STACK_MID( L, 2); | 1393 | STACK_MID( L, 2); |
1390 | shortest_ = discover_object_name_recur( L, shortest_, depth_); | 1394 | shortest_ = discover_object_name_recur( L, shortest_, depth_); |
1391 | // search in the table's metatable too | 1395 | // search in the table's metatable too |
@@ -1402,11 +1406,11 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1402 | -- depth_; | 1406 | -- depth_; |
1403 | } | 1407 | } |
1404 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} | 1408 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k {} |
1405 | STACK_MID( L, 2); | ||
1406 | } | 1409 | } |
1407 | } | 1410 | STACK_MID( L, 2); |
1408 | else if( lua_isthread( L, -1)) // o "r" {c} {fqn} ... {?} k T | 1411 | break; |
1409 | { | 1412 | |
1413 | case LUA_TTHREAD: // o "r" {c} {fqn} ... {?} k T | ||
1410 | // search in the object's uservalue if it is a table | 1414 | // search in the object's uservalue if it is a table |
1411 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k T {u} | 1415 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k T {u} |
1412 | if( lua_istable( L, -1)) | 1416 | if( lua_istable( L, -1)) |
@@ -1415,9 +1419,9 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1415 | } | 1419 | } |
1416 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k T | 1420 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k T |
1417 | STACK_MID( L, 2); | 1421 | STACK_MID( L, 2); |
1418 | } | 1422 | break; |
1419 | else if( lua_isuserdata( L, -1)) // o "r" {c} {fqn} ... {?} k U | 1423 | |
1420 | { | 1424 | case LUA_TUSERDATA: // o "r" {c} {fqn} ... {?} k U |
1421 | STACK_MID( L, 2); | 1425 | STACK_MID( L, 2); |
1422 | // search in the object's metatable (some modules are built that way) | 1426 | // search in the object's metatable (some modules are built that way) |
1423 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} | 1427 | if( lua_getmetatable( L, -1)) // o "r" {c} {fqn} ... {?} k U {mt} |
@@ -1433,8 +1437,8 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1433 | -- depth_; | 1437 | -- depth_; |
1434 | } | 1438 | } |
1435 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U | 1439 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U |
1436 | STACK_MID( L, 2); | ||
1437 | } | 1440 | } |
1441 | STACK_MID( L, 2); | ||
1438 | // search in the object's uservalue if it is a table | 1442 | // search in the object's uservalue if it is a table |
1439 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u} | 1443 | lua_getuservalue( L, -1); // o "r" {c} {fqn} ... {?} k U {u} |
1440 | if( lua_istable( L, -1)) | 1444 | if( lua_istable( L, -1)) |
@@ -1449,15 +1453,17 @@ static int discover_object_name_recur( lua_State* L, int shortest_, int depth_) | |||
1449 | } | 1453 | } |
1450 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U | 1454 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k U |
1451 | STACK_MID( L, 2); | 1455 | STACK_MID( L, 2); |
1456 | break; | ||
1452 | } | 1457 | } |
1453 | // make ready for next iteration | 1458 | // make ready for next iteration |
1454 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k | 1459 | lua_pop( L, 1); // o "r" {c} {fqn} ... {?} k |
1455 | // remove name from fqn stack | 1460 | // remove name from fqn stack |
1456 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil | 1461 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} k nil |
1457 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k | 1462 | lua_rawseti( L, fqn, depth_); // o "r" {c} {fqn} ... {?} k |
1463 | STACK_MID( L, 1); | ||
1458 | -- depth_; | 1464 | -- depth_; |
1459 | } // o "r" {c} {fqn} ... {?} | 1465 | } // o "r" {c} {fqn} ... {?} |
1460 | STACK_END( L, 0); | 1466 | STACK_MID( L, 0); |
1461 | // remove the visited table from the cache, in case a shorter path to the searched object exists | 1467 | // remove the visited table from the cache, in case a shorter path to the searched object exists |
1462 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} | 1468 | lua_pushvalue( L, -1); // o "r" {c} {fqn} ... {?} {?} |
1463 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil | 1469 | lua_pushnil( L); // o "r" {c} {fqn} ... {?} {?} nil |
@@ -1477,7 +1483,7 @@ int luaG_nameof( lua_State* L) | |||
1477 | luaL_argerror( L, what, "too many arguments."); | 1483 | luaL_argerror( L, what, "too many arguments."); |
1478 | } | 1484 | } |
1479 | 1485 | ||
1480 | // numbers, strings, booleans and nil can't be identified | 1486 | // nil, boolean, light userdata, number and string aren't identifiable |
1481 | if( lua_type( L, 1) < LUA_TTABLE) | 1487 | if( lua_type( L, 1) < LUA_TTABLE) |
1482 | { | 1488 | { |
1483 | lua_pushstring( L, luaL_typename( L, 1)); // o "type" | 1489 | lua_pushstring( L, luaL_typename( L, 1)); // o "type" |
@@ -1486,6 +1492,7 @@ int luaG_nameof( lua_State* L) | |||
1486 | } | 1492 | } |
1487 | 1493 | ||
1488 | STACK_GROW( L, 4); | 1494 | STACK_GROW( L, 4); |
1495 | STACK_CHECK( L); | ||
1489 | // this slot will contain the shortest name we found when we are done | 1496 | // this slot will contain the shortest name we found when we are done |
1490 | lua_pushnil( L); // o nil | 1497 | lua_pushnil( L); // o nil |
1491 | // push a cache that will contain all already visited tables | 1498 | // push a cache that will contain all already visited tables |
@@ -1496,6 +1503,7 @@ int luaG_nameof( lua_State* L) | |||
1496 | lua_pushglobaltable( L); // o nil {c} {fqn} _G | 1503 | lua_pushglobaltable( L); // o nil {c} {fqn} _G |
1497 | (void) discover_object_name_recur( L, 6666, 0); | 1504 | (void) discover_object_name_recur( L, 6666, 0); |
1498 | lua_pop( L, 3); // o "result" | 1505 | lua_pop( L, 3); // o "result" |
1506 | STACK_END( L, 1); | ||
1499 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" | 1507 | lua_pushstring( L, luaL_typename( L, 1)); // o "result" "type" |
1500 | lua_replace( L, -3); // "type" "result" | 1508 | lua_replace( L, -3); // "type" "result" |
1501 | return 2; | 1509 | return 2; |