Skip to content

Commit

Permalink
Merge 6da0cc0 into fb9c431
Browse files Browse the repository at this point in the history
  • Loading branch information
axstin committed May 24, 2022
2 parents fb9c431 + 6da0cc0 commit 9a2ec7e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 7 deletions.
16 changes: 10 additions & 6 deletions VM/src/ldo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,14 @@ CallInfo* luaD_growCI(lua_State* L)
return ++L->ci;
}

void luaD_checkCstack(lua_State *L)
{
if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3)))
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
}

/*
** Call a function (C or Lua). The function to be called is at *func.
** The arguments are on the stack, right after the function.
Expand All @@ -222,12 +230,8 @@ CallInfo* luaD_growCI(lua_State* L)
void luaD_call(lua_State* L, StkId func, int nResults)
{
if (++L->nCcalls >= LUAI_MAXCCALLS)
{
if (L->nCcalls == LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
else if (L->nCcalls >= (LUAI_MAXCCALLS + (LUAI_MAXCCALLS >> 3)))
luaD_throw(L, LUA_ERRERR); /* error while handing stack error */
}
luaD_checkCstack(L);

if (luau_precall(L, func, nResults) == PCRLUA)
{ /* is a Lua function? */
L->ci->flags |= LUA_CALLINFO_RETURN; /* luau_execute will stop after returning from the stack frame */
Expand Down
1 change: 1 addition & 0 deletions VM/src/ldo.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ LUAI_FUNC int luaD_pcall(lua_State* L, Pfunc func, void* u, ptrdiff_t oldtop, pt
LUAI_FUNC void luaD_reallocCI(lua_State* L, int newsize);
LUAI_FUNC void luaD_reallocstack(lua_State* L, int newsize);
LUAI_FUNC void luaD_growstack(lua_State* L, int n);
LUAI_FUNC void luaD_checkCstack(lua_State* L);

LUAI_FUNC l_noret luaD_throw(lua_State* L, int errcode);
LUAI_FUNC int luaD_rawrunprotected(lua_State* L, Pfunc f, void* ud);
2 changes: 1 addition & 1 deletion VM/src/lvmexecute.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ LUAU_NOINLINE static void luau_callTM(lua_State* L, int nparams, int res)
++L->nCcalls;

if (L->nCcalls >= LUAI_MAXCCALLS)
luaG_runerror(L, "C stack overflow");
luaD_checkCstack(L);

luaD_checkstack(L, LUA_MINSTACK);

Expand Down
70 changes: 70 additions & 0 deletions tests/conformance/errors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,76 @@ if not limitedstack then
end
end

-- C stack overflow
if not limitedstack then
local count = 1
local cso = setmetatable({}, {
__index = function(self, i)
count = count + 1
return self[i]
end,
__newindex = function(self, i, v)
count = count + 1
self[i] = v
end,
__tostring = function(self)
count = count + 1
return tostring(self)
end
})

local ehline
local function ehassert(cond)
if not cond then
ehline = debug.info(2, "l")
error()
end
end

local userdata = newproxy(true)
getmetatable(userdata).__index = print
assert(debug.info(print, "s") == "[C]")

local s, e = xpcall(tostring, function(e)
ehassert(string.find(e, "C stack overflow"))
print("after __tostring C stack overflow", count) -- 198: 1 resume + 1 xpcall + 198 luaB_tostring calls (which runs our __tostring successfully 197 times, erroring on the last attempt)
ehassert(count > 1)

local ps, pe

-- __tostring overflow (lua_call)
count = 1
ps, pe = pcall(tostring, cso)
print("after __tostring overflow in handler", count) -- 23: xpcall error handler + pcall + 23 luaB_tostring calls
ehassert(not ps and string.find(pe, "error in error handling"))
ehassert(count > 1)

-- __index overflow (callTMres)
count = 1
ps, pe = pcall(function() return cso[cso] end)
print("after __index overflow in handler", count) -- 23: xpcall error handler + pcall + 23 __index calls
ehassert(not ps and string.find(pe, "error in error handling"))
ehassert(count > 1)

-- __newindex overflow (callTM)
count = 1
ps, pe = pcall(function() cso[cso] = "kohuke" end)
print("after __newindex overflow in handler", count) -- 23: xpcall error handler + pcall + 23 __newindex calls
ehassert(not ps and string.find(pe, "error in error handling"))
ehassert(count > 1)

-- test various C __index invocations on userdata
ehassert(pcall(function() return userdata[userdata] end)) -- LOP_GETTABLE
ehassert(pcall(function() return userdata[1] end)) -- LOP_GETTABLEN
ehassert(pcall(function() return userdata.StringConstant end)) -- LOP_GETTABLEKS (luau_callTM)

return true
end, cso)

assert(not s)
assert(e == true, "error in xpcall eh, line " .. tostring(ehline))
end

--[[
local i=1
while stack[i] ~= l1 do
Expand Down

0 comments on commit 9a2ec7e

Please sign in to comment.