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-439e45a2f69549b674d6a6e2023e8debfa00a2b8.tar.gz lua-439e45a2f69549b674d6a6e2023e8debfa00a2b8.tar.bz2 lua-439e45a2f69549b674d6a6e2023e8debfa00a2b8.zip |
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) { | |||
881 | 881 | ||
882 | 882 | ||
883 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | 883 | LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { |
884 | idx = lua_absindex(L,idx); | ||
884 | if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ | 885 | if (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */ |
885 | if (!lua_isstring(L, -1)) | 886 | if (!lua_isstring(L, -1)) |
886 | luaL_error(L, "'__tostring' must return a string"); | 887 | luaL_error(L, "'__tostring' must return a string"); |
@@ -1743,6 +1743,9 @@ static struct X { int x; } x; | |||
1743 | (void)s1; /* to avoid warnings */ | 1743 | (void)s1; /* to avoid warnings */ |
1744 | lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0); | 1744 | lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0); |
1745 | } | 1745 | } |
1746 | else if EQ("Ltolstring") { | ||
1747 | luaL_tolstring(L1, getindex, NULL); | ||
1748 | } | ||
1746 | else if EQ("type") { | 1749 | else if EQ("type") { |
1747 | lua_pushstring(L1, luaL_typename(L1, getnum)); | 1750 | lua_pushstring(L1, luaL_typename(L1, getnum)); |
1748 | } | 1751 | } |
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') | |||
228 | checkmessage("return {} < XX", "table with My Type") | 228 | checkmessage("return {} < XX", "table with My Type") |
229 | checkmessage("return XX < io.stdin", "My Type with FILE*") | 229 | checkmessage("return XX < io.stdin", "My Type with FILE*") |
230 | _G.XX = nil | 230 | _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 | ||
231 | end | 247 | end |
232 | 248 | ||
233 | -- global functions | 249 | -- global functions |