mirror of https://github.com/rusefi/lua.git
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.
This commit is contained in:
parent
62fb934427
commit
439e45a2f6
|
@ -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) {
|
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 (luaL_callmeta(L, idx, "__tostring")) { /* metafield? */
|
||||||
if (!lua_isstring(L, -1))
|
if (!lua_isstring(L, -1))
|
||||||
luaL_error(L, "'__tostring' must return a string");
|
luaL_error(L, "'__tostring' must return a string");
|
||||||
|
|
3
ltests.c
3
ltests.c
|
@ -1743,6 +1743,9 @@ static struct X { int x; } x;
|
||||||
(void)s1; /* to avoid warnings */
|
(void)s1; /* to avoid warnings */
|
||||||
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
|
lua_longassert((s == NULL && s1 == NULL) || strcmp(s, s1) == 0);
|
||||||
}
|
}
|
||||||
|
else if EQ("Ltolstring") {
|
||||||
|
luaL_tolstring(L1, getindex, NULL);
|
||||||
|
}
|
||||||
else if EQ("type") {
|
else if EQ("type") {
|
||||||
lua_pushstring(L1, luaL_typename(L1, getnum));
|
lua_pushstring(L1, luaL_typename(L1, getnum));
|
||||||
}
|
}
|
||||||
|
|
|
@ -228,6 +228,22 @@ do -- named objects (field '__name')
|
||||||
checkmessage("return {} < XX", "table with My Type")
|
checkmessage("return {} < XX", "table with My Type")
|
||||||
checkmessage("return XX < io.stdin", "My Type with FILE*")
|
checkmessage("return XX < io.stdin", "My Type with FILE*")
|
||||||
_G.XX = nil
|
_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
|
end
|
||||||
|
|
||||||
-- global functions
|
-- global functions
|
||||||
|
|
Loading…
Reference in New Issue