mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-08-07 02:10:27 +00:00
Fix memory deallocation while yielding in redbean.
The yielded coroutine was removed from the stack too early, leaving it not being anchored, which led to memory freed prematurely.
This commit is contained in:
parent
fb7e8ef1e6
commit
3d997ccb35
3 changed files with 6 additions and 4 deletions
5
third_party/lua/luacallwithtrace.c
vendored
5
third_party/lua/luacallwithtrace.c
vendored
|
@ -42,7 +42,10 @@ int LuaCallWithTrace(lua_State *L, int nargs, int nres, lua_State *C) {
|
|||
lua_xmove(L, C, 1 + nargs);
|
||||
// resume the coroutine thus executing the function
|
||||
status = lua_resume(C, L, nargs, &nresults);
|
||||
lua_remove(L, 1); // remove coroutine (still) at the bottom
|
||||
// remove coroutine (still) at the bottom, but only if not yielding
|
||||
// keep it when yielding to anchor, so it's not GC-collected
|
||||
// it's going to be removed at the beggining of the request handling
|
||||
if (!canyield) lua_remove(L, 1);
|
||||
if (status != LUA_OK && status != LUA_YIELD) {
|
||||
// move the error message
|
||||
lua_xmove(C, L, 1);
|
||||
|
|
|
@ -13,7 +13,6 @@ COSMOPOLITAN_C_START_
|
|||
char *s = LuaFormatStack(L); \
|
||||
WARNF("lua stack should be empty!\n%s", s); \
|
||||
free(s); \
|
||||
lua_settop(L, 0); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
|
|
@ -2406,6 +2406,7 @@ static int LuaCallWithYield(lua_State *L) {
|
|||
// the second set of headers is not going to be sent
|
||||
lua_State *co = lua_newthread(L);
|
||||
if ((status = LuaCallWithTrace(L, 0, 0, co)) == LUA_YIELD) {
|
||||
CHECK_GT(lua_gettop(L), 0); // make sure that coroutine is anchored
|
||||
YL = co;
|
||||
generator = YieldGenerator;
|
||||
if (!isyielding) isyielding = 1;
|
||||
|
@ -3002,9 +3003,9 @@ static char *LuaOnHttpRequest(void) {
|
|||
lua_State *L = GL;
|
||||
effectivepath.p = url.path.p;
|
||||
effectivepath.n = url.path.n;
|
||||
lua_settop(L, 0); // clear Lua stack, as it needs to start fresh
|
||||
lua_getglobal(L, "OnHttpRequest");
|
||||
if (LuaCallWithYield(L) == LUA_OK) {
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return CommitOutput(GetLuaResponse());
|
||||
} else {
|
||||
LogLuaError("OnHttpRequest", lua_tostring(L, -1));
|
||||
|
@ -3012,7 +3013,6 @@ static char *LuaOnHttpRequest(void) {
|
|||
500, "Internal Server Error",
|
||||
ShouldServeCrashReportDetails() ? lua_tostring(L, -1) : NULL);
|
||||
lua_pop(L, 1); // pop error
|
||||
AssertLuaStackIsEmpty(L);
|
||||
return error;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue