ソースを参照

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.
Roberto Ierusalimschy 4 年 前
コミット
439e45a2f6
3 ファイル変更20 行追加0 行削除
  1. 1 0
      lauxlib.c
  2. 3 0
      ltests.c
  3. 16 0
      testes/errors.lua

+ 1 - 0
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");

+ 3 - 0
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));
     }

+ 16 - 0
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