diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-17 16:14:17 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2025-03-17 16:14:17 -0300 |
| commit | 3fe7be956f23385aa1950dc31e2f25127ccfc0ea (patch) | |
| tree | 1994e4fae4370d1db3e9c767338bd4f8a28e74fd /lstate.c | |
| parent | 983bc433e6a60cbc4fe3a16f1d4713bacb8e3509 (diff) | |
| download | lua-3fe7be956f23385aa1950dc31e2f25127ccfc0ea.tar.gz lua-3fe7be956f23385aa1950dc31e2f25127ccfc0ea.tar.bz2 lua-3fe7be956f23385aa1950dc31e2f25127ccfc0ea.zip | |
Bug: message handler can be overwritten
A __close metamethod can overwrite a message handler in the stack
when closing a thread or a state.
Diffstat (limited to 'lstate.c')
| -rw-r--r-- | lstate.c | 3 |
1 files changed, 3 insertions, 0 deletions
| @@ -272,7 +272,9 @@ static void close_state (lua_State *L) { | |||
| 272 | luaC_freeallobjects(L); /* just collect its objects */ | 272 | luaC_freeallobjects(L); /* just collect its objects */ |
| 273 | else { /* closing a fully built state */ | 273 | else { /* closing a fully built state */ |
| 274 | L->ci = &L->base_ci; /* unwind CallInfo list */ | 274 | L->ci = &L->base_ci; /* unwind CallInfo list */ |
| 275 | L->errfunc = 0; /* stack unwind can "throw away" the error function */ | ||
| 275 | luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ | 276 | luaD_closeprotected(L, 1, LUA_OK); /* close all upvalues */ |
| 277 | L->top.p = L->stack.p + 1; /* empty the stack to run finalizers */ | ||
| 276 | luaC_freeallobjects(L); /* collect all objects */ | 278 | luaC_freeallobjects(L); /* collect all objects */ |
| 277 | luai_userstateclose(L); | 279 | luai_userstateclose(L); |
| 278 | } | 280 | } |
| @@ -328,6 +330,7 @@ int luaE_resetthread (lua_State *L, int status) { | |||
| 328 | if (status == LUA_YIELD) | 330 | if (status == LUA_YIELD) |
| 329 | status = LUA_OK; | 331 | status = LUA_OK; |
| 330 | L->status = LUA_OK; /* so it can run __close metamethods */ | 332 | L->status = LUA_OK; /* so it can run __close metamethods */ |
| 333 | L->errfunc = 0; /* stack unwind can "throw away" the error function */ | ||
| 331 | status = luaD_closeprotected(L, 1, status); | 334 | status = luaD_closeprotected(L, 1, status); |
| 332 | if (status != LUA_OK) /* errors? */ | 335 | if (status != LUA_OK) /* errors? */ |
| 333 | luaD_seterrorobj(L, status, L->stack.p + 1); | 336 | luaD_seterrorobj(L, status, L->stack.p + 1); |
