diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-14 16:48:48 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-06-14 16:48:48 +0200 |
| commit | e3f3288597dc62c9c26d89f92e396bc3abf4b408 (patch) | |
| tree | 250beb191624642ffbecbcc8848c4c7b575420e3 | |
| parent | 4d364d3e77667b70bf3261da004f4990ef0c3ada (diff) | |
| download | lanes-e3f3288597dc62c9c26d89f92e396bc3abf4b408.tar.gz lanes-e3f3288597dc62c9c26d89f92e396bc3abf4b408.tar.bz2 lanes-e3f3288597dc62c9c26d89f92e396bc3abf4b408.zip | |
Fix error handling when indexing a lane with unexpected data
| -rw-r--r-- | src/lane.cpp | 20 | ||||
| -rw-r--r-- | tests/basic.lua | 4 |
2 files changed, 18 insertions, 6 deletions
diff --git a/src/lane.cpp b/src/lane.cpp index 17c4126..a998e9c 100644 --- a/src/lane.cpp +++ b/src/lane.cpp | |||
| @@ -352,10 +352,20 @@ static LUAG_FUNC(thread_index) | |||
| 352 | 352 | ||
| 353 | default: // unknown key | 353 | default: // unknown key |
| 354 | lua_getmetatable(L_, kSelf); // L_: mt | 354 | lua_getmetatable(L_, kSelf); // L_: mt |
| 355 | std::ignore = luaG_getfield(L_, -1, "cached_error"); // L_: mt error | 355 | kCachedError.pushKey(L_); // L_: mt kCachedError |
| 356 | luaG_pushstring(L_, "Unknown key: "); // L_: mt error "Unknown key: " | 356 | lua_rawget(L_, -2); // L_: mt error() |
| 357 | lua_pushvalue(L_, kKey); // L_: mt error "Unknown key: " k | 357 | if (luaG_type(L_, -1) != LuaType::FUNCTION) { |
| 358 | lua_concat(L_, 2); // L_: mt error "Unknown key: <k>" | 358 | raise_luaL_error(L_, "INTERNAL ERROR: cached error() is a %s, not a function", luaG_typename(L_, -1).data()); |
| 359 | } | ||
| 360 | luaG_pushstring(L_, "Unknown key: "); // L_: mt error() "Unknown key: " | ||
| 361 | kCachedTostring.pushKey(L_); // L_: mt error() "Unknown key: " kCachedTostring | ||
| 362 | lua_rawget(L_, -4); // L_: mt error() "Unknown key: " tostring() | ||
| 363 | if (luaG_type(L_, -1) != LuaType::FUNCTION) { | ||
| 364 | raise_luaL_error(L_, "INTERNAL ERROR: cached tostring() is a %s, not a function", luaG_typename(L_, -1).data()); | ||
| 365 | } | ||
| 366 | lua_pushvalue(L_, kKey); // L_: mt error() "Unknown key: " tostring() k | ||
| 367 | lua_call(L_, 1, 1); // L_: mt error() "Unknown key: " "k" | ||
| 368 | lua_concat(L_, 2); // L_: mt error() "Unknown key: <k>" | ||
| 359 | lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return // L_: mt | 369 | lua_call(L_, 1, 0); // error( "Unknown key: " .. key) -> doesn't return // L_: mt |
| 360 | raise_luaL_error(L_, "%s[%s]: should not get here!", _lane->debugName.data(), luaG_typename(L_, kKey).data()); | 370 | raise_luaL_error(L_, "%s[%s]: should not get here!", _lane->debugName.data(), luaG_typename(L_, kKey).data()); |
| 361 | } | 371 | } |
| @@ -965,7 +975,7 @@ namespace { | |||
| 965 | } // namespace local | 975 | } // namespace local |
| 966 | } // namespace | 976 | } // namespace |
| 967 | 977 | ||
| 968 | // contains keys: { __gc, __index, cached_error, cached_tostring, cancel, join, get_debug_threadname } | 978 | // contains keys: { __close, __gc, __index, kCachedError, kCachedTostring, cancel, get_debug_threadname, join } |
| 969 | void Lane::PushMetatable(lua_State* L_) | 979 | void Lane::PushMetatable(lua_State* L_) |
| 970 | { | 980 | { |
| 971 | STACK_CHECK_START_REL(L_, 0); | 981 | STACK_CHECK_START_REL(L_, 0); |
diff --git a/tests/basic.lua b/tests/basic.lua index ae8ebd9..6282e3e 100644 --- a/tests/basic.lua +++ b/tests/basic.lua | |||
| @@ -92,6 +92,8 @@ local task_launch= lanes_gen("", { globals={hey=true}, gc_cb = gc_cb}, task) | |||
| 92 | -- 'task_launch' is a factory of multithreaded tasks, we can launch several: | 92 | -- 'task_launch' is a factory of multithreaded tasks, we can launch several: |
| 93 | 93 | ||
| 94 | local lane1= task_launch(100,200,3) | 94 | local lane1= task_launch(100,200,3) |
| 95 | assert.fails(function() print(lane1[lane1]) end) -- indexing the lane with anything other than a string or a number should fail | ||
| 96 | |||
| 95 | local lane2= task_launch(200,300,4) | 97 | local lane2= task_launch(200,300,4) |
| 96 | 98 | ||
| 97 | -- At this stage, states may be "pending", "running" or "done" | 99 | -- At this stage, states may be "pending", "running" or "done" |
| @@ -435,7 +437,7 @@ local function chunk2(linda) | |||
| 435 | assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src") | 437 | assert(config.strip_functions and info.short_src=="?" or string.match(info.short_src, "^.*basic.lua$"), "bad info.short_src") |
| 436 | -- These vary so let's not be picky (they're there..) | 438 | -- These vary so let's not be picky (they're there..) |
| 437 | -- | 439 | -- |
| 438 | assert(info.linedefined == 420, "bad linedefined") -- start of 'chunk2' | 440 | assert(info.linedefined == 422, "bad linedefined") -- start of 'chunk2' |
| 439 | assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' | 441 | assert(config.strip_functions and info.currentline==-1 or info.currentline > info.linedefined, "bad currentline") -- line of 'debug.getinfo' |
| 440 | assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' | 442 | assert(info.lastlinedefined > info.currentline, "bad lastlinedefined") -- end of 'chunk2' |
| 441 | local k,func= linda:receive("down") | 443 | local k,func= linda:receive("down") |
