aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-03-12 15:51:16 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2025-03-12 15:51:16 -0300
commitc931d86e98da320c71da70c16d44aa28e9755520 (patch)
tree2c73ee84120f8f7983d883b3f46546e0676f6ba6
parentd9e0f64a5de699a620771af299ea22f522c72f19 (diff)
downloadlua-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.c4
-rw-r--r--ldo.c36
-rw-r--r--ldo.h1
-rw-r--r--lstate.c2
-rw-r--r--testes/errors.lua4
5 files changed, 25 insertions, 22 deletions
diff --git a/ldebug.c b/ldebug.c
index 18bdc595..a3202981 100644
--- a/ldebug.c
+++ b/ldebug.c
@@ -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
diff --git a/ldo.c b/ldo.c
index 84f7bbb2..b0d37bf7 100644
--- a/ldo.c
+++ b/ldo.c
@@ -102,24 +102,13 @@ struct lua_longjmp {
102 102
103 103
104void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop) { 104void 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 */
183l_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 */
diff --git a/ldo.h b/ldo.h
index ea1655e1..465f4fb8 100644
--- a/ldo.h
+++ b/ldo.h
@@ -67,6 +67,7 @@
67/* type of protected functions, to be ran by 'runprotected' */ 67/* type of protected functions, to be ran by 'runprotected' */
68typedef void (*Pfunc) (lua_State *L, void *ud); 68typedef void (*Pfunc) (lua_State *L, void *ud);
69 69
70LUAI_FUNC l_noret luaD_errerr (lua_State *L);
70LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop); 71LUAI_FUNC void luaD_seterrorobj (lua_State *L, TStatus errcode, StkId oldtop);
71LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z, 72LUAI_FUNC TStatus luaD_protectedparser (lua_State *L, ZIO *z,
72 const char *name, 73 const char *name,
diff --git a/lstate.c b/lstate.c
index 69ddef40..ed5ccaaa 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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
46assert(doit("error('hi', 0)") == 'hi') 46assert(doit("error('hi', 0)") == 'hi')
47 47
48-- test nil error message 48-- test nil error message
49assert(doit("error()") == "<error object is nil>") 49assert(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)