diff options
author | Mike Pall <mike> | 2023-09-21 04:40:48 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2023-09-21 04:40:48 +0200 |
commit | a5d2f70c73e406beb617afa829a7af5b8c1d842c (patch) | |
tree | cc16d1cc36064e5b752162ba14548a648d6f6082 /src | |
parent | e86990f7f24a94b0897061f25a84547fe1108bed (diff) | |
download | luajit-a5d2f70c73e406beb617afa829a7af5b8c1d842c.tar.gz luajit-a5d2f70c73e406beb617afa829a7af5b8c1d842c.tar.bz2 luajit-a5d2f70c73e406beb617afa829a7af5b8c1d842c.zip |
Handle OOM error on stack resize in coroutine.resume and lua_checkstack.
Thanks to Peter Cawley. #1066
Diffstat (limited to 'src')
-rw-r--r-- | src/lib_base.c | 5 | ||||
-rw-r--r-- | src/lj_api.c | 7 | ||||
-rw-r--r-- | src/lj_state.c | 12 | ||||
-rw-r--r-- | src/lj_state.h | 1 |
4 files changed, 23 insertions, 2 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index dd54b9f9..4e6f8a30 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -616,7 +616,10 @@ static int ffh_resume(lua_State *L, lua_State *co, int wrap) | |||
616 | setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); | 616 | setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); |
617 | return FFH_RES(2); | 617 | return FFH_RES(2); |
618 | } | 618 | } |
619 | lj_state_growstack(co, (MSize)(L->top - L->base)); | 619 | if (lj_state_cpgrowstack(co, (MSize)(L->top - L->base)) != LUA_OK) { |
620 | cTValue *msg = --co->top; | ||
621 | lj_err_callermsg(L, strVdata(msg)); | ||
622 | } | ||
620 | return FFH_RETRY; | 623 | return FFH_RETRY; |
621 | } | 624 | } |
622 | 625 | ||
diff --git a/src/lj_api.c b/src/lj_api.c index 386bcada..d4048d79 100644 --- a/src/lj_api.c +++ b/src/lj_api.c | |||
@@ -104,7 +104,12 @@ LUA_API int lua_checkstack(lua_State *L, int size) | |||
104 | if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) { | 104 | if (size > LUAI_MAXCSTACK || (L->top - L->base + size) > LUAI_MAXCSTACK) { |
105 | return 0; /* Stack overflow. */ | 105 | return 0; /* Stack overflow. */ |
106 | } else if (size > 0) { | 106 | } else if (size > 0) { |
107 | lj_state_checkstack(L, (MSize)size); | 107 | int avail = (int)(mref(L->maxstack, TValue) - L->top); |
108 | if (size > avail && | ||
109 | lj_state_cpgrowstack(L, (MSize)(size - avail)) != LUA_OK) { | ||
110 | L->top--; | ||
111 | return 0; /* Out of memory. */ | ||
112 | } | ||
108 | } | 113 | } |
109 | return 1; | 114 | return 1; |
110 | } | 115 | } |
diff --git a/src/lj_state.c b/src/lj_state.c index 6b3f58ff..569e3f38 100644 --- a/src/lj_state.c +++ b/src/lj_state.c | |||
@@ -130,6 +130,18 @@ void LJ_FASTCALL lj_state_growstack1(lua_State *L) | |||
130 | lj_state_growstack(L, 1); | 130 | lj_state_growstack(L, 1); |
131 | } | 131 | } |
132 | 132 | ||
133 | static TValue *cpgrowstack(lua_State *co, lua_CFunction dummy, void *ud) | ||
134 | { | ||
135 | UNUSED(dummy); | ||
136 | lj_state_growstack(co, *(MSize *)ud); | ||
137 | return NULL; | ||
138 | } | ||
139 | |||
140 | int LJ_FASTCALL lj_state_cpgrowstack(lua_State *L, MSize need) | ||
141 | { | ||
142 | return lj_vm_cpcall(L, NULL, &need, cpgrowstack); | ||
143 | } | ||
144 | |||
133 | /* Allocate basic stack for new state. */ | 145 | /* Allocate basic stack for new state. */ |
134 | static void stack_init(lua_State *L1, lua_State *L) | 146 | static void stack_init(lua_State *L1, lua_State *L) |
135 | { | 147 | { |
diff --git a/src/lj_state.h b/src/lj_state.h index db67f03b..3850e5a1 100644 --- a/src/lj_state.h +++ b/src/lj_state.h | |||
@@ -18,6 +18,7 @@ LJ_FUNC void lj_state_relimitstack(lua_State *L); | |||
18 | LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used); | 18 | LJ_FUNC void lj_state_shrinkstack(lua_State *L, MSize used); |
19 | LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need); | 19 | LJ_FUNCA void LJ_FASTCALL lj_state_growstack(lua_State *L, MSize need); |
20 | LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L); | 20 | LJ_FUNC void LJ_FASTCALL lj_state_growstack1(lua_State *L); |
21 | LJ_FUNC int LJ_FASTCALL lj_state_cpgrowstack(lua_State *L, MSize need); | ||
21 | 22 | ||
22 | static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need) | 23 | static LJ_AINLINE void lj_state_checkstack(lua_State *L, MSize need) |
23 | { | 24 | { |