Skip to content

Commit 439e45a

Browse files
committed
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.
1 parent 62fb934 commit 439e45a

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

lauxlib.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,7 @@ LUALIB_API lua_Integer luaL_len (lua_State *L, int idx) {
881881

882882

883883
LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
884+
idx = lua_absindex(L,idx);
884885
if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
885886
if (!lua_isstring(L, -1))
886887
luaL_error(L, "'__tostring' must return a string");

ltests.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1743,6 +1743,9 @@ static struct X { int x; } x;
17431743
(void)s1; /* to avoid warnings */
17441744
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
17451745
}
1746+
else if EQ("Ltolstring") {
1747+
luaL_tolstring(L1, getindex, NULL);
1748+
}
17461749
else if EQ("type") {
17471750
lua_pushstring(L1, luaL_typename(L1, getnum));
17481751
}

testes/errors.lua

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,22 @@ do -- named objects (field '__name')
228228
checkmessage("return {} < XX", "table with My Type")
229229
checkmessage("return XX < io.stdin", "My Type with FILE*")
230230
_G.XX = nil
231+
232+
if T then -- extra tests for 'luaL_tolstring'
233+
-- bug in 5.4.3; 'luaL_tolstring' with negative indices
234+
local x = setmetatable({}, {__name="TABLE"})
235+
assert(T.testC("Ltolstring -1; return 1", x) == tostring(x))
236+
237+
local a, b = T.testC("pushint 10; Ltolstring -2; return 2", x)
238+
assert(a == 10 and b == tostring(x))
239+
240+
setmetatable(x, {__tostring=function (o)
241+
assert(o == x)
242+
return "ABC"
243+
end})
244+
a, b, c = T.testC("pushint 10; Ltolstring -2; return 3", x)
245+
assert(a == x and b == 10 and c == "ABC")
246+
end
231247
end
232248

233249
-- global functions

0 commit comments

Comments
 (0)