mirror of
https://github.com/lua/lua.git
synced 2025-07-04 15:09:38 +00:00
'luaD_seterrorobj' should not raise errors
This function can be called unprotected, so it should not raise any kind of errors. (It could raise a memory-allocation error when creating a message).
This commit is contained in:
parent
d9e0f64a5d
commit
c931d86e98
5 changed files with 25 additions and 22 deletions
4
ldebug.c
4
ldebug.c
|
@ -832,6 +832,10 @@ l_noret luaG_errormsg (lua_State *L) {
|
||||||
L->top.p++; /* assume EXTRA_STACK */
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
luaD_callnoyield(L, L->top.p - 2, 1); /* call it */
|
luaD_callnoyield(L, L->top.p - 2, 1); /* call it */
|
||||||
}
|
}
|
||||||
|
if (ttisnil(s2v(L->top.p - 1))) { /* error object is nil? */
|
||||||
|
/* change it to a proper message */
|
||||||
|
setsvalue2s(L, L->top.p - 1, luaS_newliteral(L, "<no error object>"));
|
||||||
|
}
|
||||||
luaD_throw(L, LUA_ERRRUN);
|
luaD_throw(L, LUA_ERRRUN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
36
ldo.c
36
ldo.c
|
@ -102,24 +102,13 @@ struct lua_longjmp {
|
||||||
|
|
||||||
|
|
||||||
void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
|
void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) {
|
||||||
switch (errcode) {
|
if (errcode == LUA_ERRMEM) { /* memory error? */
|
||||||
case LUA_ERRMEM: { /* memory error? */
|
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
||||||
setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */
|
}
|
||||||
break;
|
else {
|
||||||
}
|
lua_assert(errorstatus(errcode)); /* must be a real error */
|
||||||
case LUA_ERRERR: {
|
lua_assert(!ttisnil(s2v(L->top.p - 1))); /* with a non-nil object */
|
||||||
setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling"));
|
setobjs2s(L, oldtop, L->top.p - 1); /* move it to 'oldtop' */
|
||||||
break;
|
|
||||||
}
|
|
||||||
default: {
|
|
||||||
lua_assert(errorstatus(errcode)); /* must be a real error */
|
|
||||||
if (!ttisnil(s2v(L->top.p - 1))) { /* error object is not nil? */
|
|
||||||
setobjs2s(L, oldtop, L->top.p - 1); /* move it to 'oldtop' */
|
|
||||||
}
|
|
||||||
else /* change it to a proper message */
|
|
||||||
setsvalue2s(L, oldtop, luaS_newliteral(L, "<error object is nil>"));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
L->top.p = oldtop + 1; /* top goes back to old top plus error object */
|
L->top.p = oldtop + 1; /* top goes back to old top plus error object */
|
||||||
}
|
}
|
||||||
|
@ -190,6 +179,15 @@ TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
|
||||||
#define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE)
|
#define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE)
|
||||||
|
|
||||||
|
|
||||||
|
/* raise an error while running the message handler */
|
||||||
|
l_noret luaD_errerr (lua_State *L) {
|
||||||
|
TString *msg = luaS_newliteral(L, "error in error handling");
|
||||||
|
setsvalue2s(L, L->top.p, msg);
|
||||||
|
L->top.p++; /* assume EXTRA_STACK */
|
||||||
|
luaD_throw(L, LUA_ERRERR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** In ISO C, any pointer use after the pointer has been deallocated is
|
** In ISO C, any pointer use after the pointer has been deallocated is
|
||||||
** undefined behavior. So, before a stack reallocation, all pointers
|
** undefined behavior. So, before a stack reallocation, all pointers
|
||||||
|
@ -317,7 +315,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) {
|
||||||
a stack error; cannot grow further than that. */
|
a stack error; cannot grow further than that. */
|
||||||
lua_assert(stacksize(L) == ERRORSTACKSIZE);
|
lua_assert(stacksize(L) == ERRORSTACKSIZE);
|
||||||
if (raiseerror)
|
if (raiseerror)
|
||||||
luaD_throw(L, LUA_ERRERR); /* error inside message handler */
|
luaD_errerr(L); /* error inside message handler */
|
||||||
return 0; /* if not 'raiseerror', just signal it */
|
return 0; /* if not 'raiseerror', just signal it */
|
||||||
}
|
}
|
||||||
else if (n < MAXSTACK) { /* avoids arithmetic overflows */
|
else if (n < MAXSTACK) { /* avoids arithmetic overflows */
|
||||||
|
|
1
ldo.h
1
ldo.h
|
@ -67,6 +67,7 @@
|
||||||
/* type of protected functions, to be ran by 'runprotected' */
|
/* type of protected functions, to be ran by 'runprotected' */
|
||||||
typedef void (*Pfunc) (lua_State *L, void *ud);
|
typedef void (*Pfunc) (lua_State *L, void *ud);
|
||||||
|
|
||||||
|
LUAI_FUNC l_noret luaD_errerr (lua_State *L);
|
||||||
LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop);
|
LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop);
|
||||||
LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z,
|
LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z,
|
||||||
const char *name,
|
const char *name,
|
||||||
|
|
2
lstate.c
2
lstate.c
|
@ -132,7 +132,7 @@ void luaE_checkcstack (lua_State *L) {
|
||||||
if (getCcalls(L) == LUAI_MAXCCALLS)
|
if (getCcalls(L) == LUAI_MAXCCALLS)
|
||||||
luaG_runerror(L, "C stack overflow");
|
luaG_runerror(L, "C stack overflow");
|
||||||
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11))
|
||||||
luaD_throw(L, LUA_ERRERR); /* error while handling stack error */
|
luaD_errerr(L); /* error while handling stack error */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -46,7 +46,7 @@ end
|
||||||
assert(doit("error('hi', 0)") == 'hi')
|
assert(doit("error('hi', 0)") == 'hi')
|
||||||
|
|
||||||
-- test nil error message
|
-- test nil error message
|
||||||
assert(doit("error()") == "<error object is nil>")
|
assert(doit("error()") == "<no error object>")
|
||||||
|
|
||||||
|
|
||||||
-- test common errors/errors that crashed in the past
|
-- test common errors/errors that crashed in the past
|
||||||
|
@ -614,7 +614,7 @@ do
|
||||||
assert(not res and msg == t)
|
assert(not res and msg == t)
|
||||||
|
|
||||||
res, msg = pcall(function () error(nil) end)
|
res, msg = pcall(function () error(nil) end)
|
||||||
assert(not res and msg == "<error object is nil>")
|
assert(not res and msg == "<no error object>")
|
||||||
|
|
||||||
local function f() error{msg='x'} end
|
local function f() error{msg='x'} end
|
||||||
res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
|
res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue