diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-12 15:51:16 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-12 15:51:16 -0300 |
commit | c931d86e98da320c71da70c16d44aa28e9755520 (patch) | |
tree | 2c73ee84120f8f7983d883b3f46546e0676f6ba6 | |
parent | d9e0f64a5de699a620771af299ea22f522c72f19 (diff) | |
download | lua-c931d86e98da320c71da70c16d44aa28e9755520.tar.gz lua-c931d86e98da320c71da70c16d44aa28e9755520.tar.bz2 lua-c931d86e98da320c71da70c16d44aa28e9755520.zip |
'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).
-rw-r--r-- | ldebug.c | 4 | ||||
-rw-r--r-- | ldo.c | 36 | ||||
-rw-r--r-- | ldo.h | 1 | ||||
-rw-r--r-- | lstate.c | 2 | ||||
-rw-r--r-- | testes/errors.lua | 4 |
5 files changed, 25 insertions, 22 deletions
@@ -832,6 +832,10 @@ l_noret luaG_errormsg (lua_State *L) { | |||
832 | L->top.p++; /* assume EXTRA_STACK */ | 832 | L->top.p++; /* assume EXTRA_STACK */ |
833 | luaD_callnoyield(L, L->top.p - 2, 1); /* call it */ | 833 | luaD_callnoyield(L, L->top.p - 2, 1); /* call it */ |
834 | } | 834 | } |
835 | if (ttisnil(s2v(L->top.p - 1))) { /* error object is nil? */ | ||
836 | /* change it to a proper message */ | ||
837 | setsvalue2s(L, L->top.p - 1, luaS_newliteral(L, "<no error object>")); | ||
838 | } | ||
835 | luaD_throw(L, LUA_ERRRUN); | 839 | luaD_throw(L, LUA_ERRRUN); |
836 | } | 840 | } |
837 | 841 | ||
@@ -102,24 +102,13 @@ struct lua_longjmp { | |||
102 | 102 | ||
103 | 103 | ||
104 | void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) { | 104 | void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) { |
105 | switch (errcode) { | 105 | if (errcode == LUA_ERRMEM) { /* memory error? */ |
106 | case LUA_ERRMEM: { /* memory error? */ | 106 | setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ |
107 | setsvalue2s(L, oldtop, G(L)->memerrmsg); /* reuse preregistered msg. */ | 107 | } |
108 | break; | 108 | else { |
109 | } | 109 | lua_assert(errorstatus(errcode)); /* must be a real error */ |
110 | case LUA_ERRERR: { | 110 | lua_assert(!ttisnil(s2v(L->top.p - 1))); /* with a non-nil object */ |
111 | setsvalue2s(L, oldtop, luaS_newliteral(L, "error in error handling")); | 111 | setobjs2s(L, oldtop, L->top.p - 1); /* move it to 'oldtop' */ |
112 | break; | ||
113 | } | ||
114 | default: { | ||
115 | lua_assert(errorstatus(errcode)); /* must be a real error */ | ||
116 | if (!ttisnil(s2v(L->top.p - 1))) { /* error object is not nil? */ | ||
117 | setobjs2s(L, oldtop, L->top.p - 1); /* move it to 'oldtop' */ | ||
118 | } | ||
119 | else /* change it to a proper message */ | ||
120 | setsvalue2s(L, oldtop, luaS_newliteral(L, "<error object is nil>")); | ||
121 | break; | ||
122 | } | ||
123 | } | 112 | } |
124 | L->top.p = oldtop + 1; /* top goes back to old top plus error object */ | 113 | L->top.p = oldtop + 1; /* top goes back to old top plus error object */ |
125 | } | 114 | } |
@@ -190,6 +179,15 @@ TStatus luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) { | |||
190 | #define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE) | 179 | #define ERRORSTACKSIZE (MAXSTACK + STACKERRSPACE) |
191 | 180 | ||
192 | 181 | ||
182 | /* raise an error while running the message handler */ | ||
183 | l_noret luaD_errerr (lua_State *L) { | ||
184 | TString *msg = luaS_newliteral(L, "error in error handling"); | ||
185 | setsvalue2s(L, L->top.p, msg); | ||
186 | L->top.p++; /* assume EXTRA_STACK */ | ||
187 | luaD_throw(L, LUA_ERRERR); | ||
188 | } | ||
189 | |||
190 | |||
193 | /* | 191 | /* |
194 | ** In ISO C, any pointer use after the pointer has been deallocated is | 192 | ** In ISO C, any pointer use after the pointer has been deallocated is |
195 | ** undefined behavior. So, before a stack reallocation, all pointers | 193 | ** undefined behavior. So, before a stack reallocation, all pointers |
@@ -317,7 +315,7 @@ int luaD_growstack (lua_State *L, int n, int raiseerror) { | |||
317 | a stack error; cannot grow further than that. */ | 315 | a stack error; cannot grow further than that. */ |
318 | lua_assert(stacksize(L) == ERRORSTACKSIZE); | 316 | lua_assert(stacksize(L) == ERRORSTACKSIZE); |
319 | if (raiseerror) | 317 | if (raiseerror) |
320 | luaD_throw(L, LUA_ERRERR); /* error inside message handler */ | 318 | luaD_errerr(L); /* error inside message handler */ |
321 | return 0; /* if not 'raiseerror', just signal it */ | 319 | return 0; /* if not 'raiseerror', just signal it */ |
322 | } | 320 | } |
323 | else if (n < MAXSTACK) { /* avoids arithmetic overflows */ | 321 | else if (n < MAXSTACK) { /* avoids arithmetic overflows */ |
@@ -67,6 +67,7 @@ | |||
67 | /* type of protected functions, to be ran by 'runprotected' */ | 67 | /* type of protected functions, to be ran by 'runprotected' */ |
68 | typedef void (*Pfunc) (lua_State *L, void *ud); | 68 | typedef void (*Pfunc) (lua_State *L, void *ud); |
69 | 69 | ||
70 | LUAI_FUNC l_noret luaD_errerr (lua_State *L); | ||
70 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop); | 71 | LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop); |
71 | LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z, | 72 | LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z, |
72 | const char *name, | 73 | const char *name, |
@@ -132,7 +132,7 @@ void luaE_checkcstack (lua_State *L) { | |||
132 | if (getCcalls(L) == LUAI_MAXCCALLS) | 132 | if (getCcalls(L) == LUAI_MAXCCALLS) |
133 | luaG_runerror(L, "C stack overflow"); | 133 | luaG_runerror(L, "C stack overflow"); |
134 | else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) | 134 | else if (getCcalls(L) >= (LUAI_MAXCCALLS / 10 * 11)) |
135 | luaD_throw(L, LUA_ERRERR); /* error while handling stack error */ | 135 | luaD_errerr(L); /* error while handling stack error */ |
136 | } | 136 | } |
137 | 137 | ||
138 | 138 | ||
diff --git a/testes/errors.lua b/testes/errors.lua index 8ef26757..d83e6023 100644 --- a/testes/errors.lua +++ b/testes/errors.lua | |||
@@ -46,7 +46,7 @@ end | |||
46 | assert(doit("error('hi', 0)") == 'hi') | 46 | assert(doit("error('hi', 0)") == 'hi') |
47 | 47 | ||
48 | -- test nil error message | 48 | -- test nil error message |
49 | assert(doit("error()") == "<error object is nil>") | 49 | assert(doit("error()") == "<no error object>") |
50 | 50 | ||
51 | 51 | ||
52 | -- test common errors/errors that crashed in the past | 52 | -- test common errors/errors that crashed in the past |
@@ -614,7 +614,7 @@ do | |||
614 | assert(not res and msg == t) | 614 | assert(not res and msg == t) |
615 | 615 | ||
616 | res, msg = pcall(function () error(nil) end) | 616 | res, msg = pcall(function () error(nil) end) |
617 | assert(not res and msg == "<error object is nil>") | 617 | assert(not res and msg == "<no error object>") |
618 | 618 | ||
619 | local function f() error{msg='x'} end | 619 | local function f() error{msg='x'} end |
620 | res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) | 620 | res, msg = xpcall(f, function (r) return {msg=r.msg..'y'} end) |