diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-07-22 13:48:43 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2021-07-22 13:48:43 -0300 |
commit | 439e45a2f69549b674d6a6e2023e8debfa00a2b8 (patch) | |
tree | 416db940cc3e4826119fda14d47f579b60cfb99b | |
parent | 62fb93442753cbfb828335cd172e71471dffd536 (diff) | |
download | lua-github-439e45a2f69549b674d6a6e2023e8debfa00a2b8.tar.gz |
Bug: luaL_tolstring may get confused with negative index
When object has a '__name' metafield, 'luaL_tolstring' used the
received index after pushing a string on the stack.
-rw-r--r-- | lauxlib.c | 1 | ||||
-rw-r--r-- | ltests.c | 3 | ||||
-rw-r--r-- | testes/errors.lua | 16 |
3 files changed, 20 insertions, 0 deletions
@@ -881,6 +881,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) { LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { + idx = lua_absindex(L,idx); if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ if (!lua_isstring(L, -1)) luaL_error(L, "'__tostring' must return a string"); @@ -1743,6 +1743,9 @@ static struct X { int x; } x; (void)s1; /* to avoid warnings */ lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0); } + else if EQ("Ltolstring") { + luaL_tolstring(L1, getindex, NULL); + } else if EQ("type") { lua_pushstring(L1, luaL_typename(L1, getnum)); } diff --git a/testes/errors.lua b/testes/errors.lua index 825f37c2..a7dc479a 100644 --- a/testes/errors.lua +++ b/testes/errors.lua @@ -228,6 +228,22 @@ do -- named objects (field '__name') checkmessage("return {} < XX", "table with My Type") checkmessage("return XX < io.stdin", "My Type with FILE*") _G.XX = nil + + if T then -- extra tests for 'luaL_tolstring' + -- bug in 5.4.3; 'luaL_tolstring' with negative indices + local x = setmetatable({}, {__name="TABLE"}) + assert(T.testC("Ltolstring -1; return 1", x) == tostring(x)) + + local a, b = T.testC("pushint 10; Ltolstring -2; return 2", x) + assert(a == 10 and b == tostring(x)) + + setmetatable(x, {__tostring=function (o) + assert(o == x) + return "ABC" + end}) + a, b, c = T.testC("pushint 10; Ltolstring -2; return 3", x) + assert(a == x and b == 10 and c == "ABC") + end end -- global functions |