From 439e45a2f69549b674d6a6e2023e8debfa00a2b8 Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy Date: Thu, 22 Jul 2021 13:48:43 -0300 Subject: 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. --- lauxlib.c | 1 + ltests.c | 3 +++ testes/errors.lua | 16 ++++++++++++++++ 3 files changed, 20 insertions(+) diff --git a/lauxlib.c b/lauxlib.c index 94835ef9..8ed1da11 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -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"); diff --git a/ltests.c b/ltests.c index a50f7830..97834e38 100644 --- a/ltests.c +++ b/ltests.c @@ -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 -- cgit v1.2.1