aboutsummaryrefslogtreecommitdiff
path: root/ltm.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-03-29 15:10:50 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2024-03-29 15:10:50 -0300
commit88a50ffa715483e7187c0d7d6caaf708ebacf756 (patch)
treeabd032613bb066ebf4b4d3d2cb2e031347945c0a /ltm.c
parent86a8e74824b3ec7918e3dbeaff222bb1ea1ec22f (diff)
downloadlua-88a50ffa715483e7187c0d7d6caaf708ebacf756.tar.gz
lua-88a50ffa715483e7187c0d7d6caaf708ebacf756.tar.bz2
lua-88a50ffa715483e7187c0d7d6caaf708ebacf756.zip
Fixed dangling 'StkId' in 'luaV_finishget'
Bug introduced in 05932567.
Diffstat (limited to 'ltm.c')
-rw-r--r--ltm.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/ltm.c b/ltm.c
index c28f9122..236f3bb4 100644
--- a/ltm.c
+++ b/ltm.c
@@ -116,8 +116,8 @@ void luaT_callTM (lua_State *L, const TValue *f, const TValue *p1,
116} 116}
117 117
118 118
119void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1, 119int luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
120 const TValue *p2, StkId res) { 120 const TValue *p2, StkId res) {
121 ptrdiff_t result = savestack(L, res); 121 ptrdiff_t result = savestack(L, res);
122 StkId func = L->top.p; 122 StkId func = L->top.p;
123 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */ 123 setobj2s(L, func, f); /* push function (assume EXTRA_STACK) */
@@ -131,6 +131,7 @@ void luaT_callTMres (lua_State *L, const TValue *f, const TValue *p1,
131 luaD_callnoyield(L, func, 1); 131 luaD_callnoyield(L, func, 1);
132 res = restorestack(L, result); 132 res = restorestack(L, result);
133 setobjs2s(L, res, --L->top.p); /* move result to its place */ 133 setobjs2s(L, res, --L->top.p); /* move result to its place */
134 return ttypetag(s2v(res)); /* return tag of the result */
134} 135}
135 136
136 137
@@ -139,15 +140,16 @@ static int callbinTM (lua_State *L, const TValue *p1, const TValue *p2,
139 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */ 140 const TValue *tm = luaT_gettmbyobj(L, p1, event); /* try first operand */
140 if (notm(tm)) 141 if (notm(tm))
141 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */ 142 tm = luaT_gettmbyobj(L, p2, event); /* try second operand */
142 if (notm(tm)) return 0; 143 if (notm(tm))
143 luaT_callTMres(L, tm, p1, p2, res); 144 return -1; /* tag method not found */
144 return 1; 145 else /* call tag method and return the tag of the result */
146 return luaT_callTMres(L, tm, p1, p2, res);
145} 147}
146 148
147 149
148void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2, 150void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
149 StkId res, TMS event) { 151 StkId res, TMS event) {
150 if (l_unlikely(!callbinTM(L, p1, p2, res, event))) { 152 if (l_unlikely(callbinTM(L, p1, p2, res, event) < 0)) {
151 switch (event) { 153 switch (event) {
152 case TM_BAND: case TM_BOR: case TM_BXOR: 154 case TM_BAND: case TM_BOR: case TM_BXOR:
153 case TM_SHL: case TM_SHR: case TM_BNOT: { 155 case TM_SHL: case TM_SHR: case TM_BNOT: {
@@ -164,11 +166,14 @@ void luaT_trybinTM (lua_State *L, const TValue *p1, const TValue *p2,
164} 166}
165 167
166 168
169/*
170** The use of 'p1' after 'callbinTM' is safe because, when a tag
171** method is not found, 'callbinTM' cannot change the stack.
172*/
167void luaT_tryconcatTM (lua_State *L) { 173void luaT_tryconcatTM (lua_State *L) {
168 StkId top = L->top.p; 174 StkId p1 = L->top.p - 2; /* first argument */
169 if (l_unlikely(!callbinTM(L, s2v(top - 2), s2v(top - 1), top - 2, 175 if (l_unlikely(callbinTM(L, s2v(p1), s2v(p1 + 1), p1, TM_CONCAT) < 0))
170 TM_CONCAT))) 176 luaG_concaterror(L, s2v(p1), s2v(p1 + 1));
171 luaG_concaterror(L, s2v(top - 2), s2v(top - 1));
172} 177}
173 178
174 179
@@ -200,17 +205,17 @@ void luaT_trybiniTM (lua_State *L, const TValue *p1, lua_Integer i2,
200*/ 205*/
201int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2, 206int luaT_callorderTM (lua_State *L, const TValue *p1, const TValue *p2,
202 TMS event) { 207 TMS event) {
203 if (callbinTM(L, p1, p2, L->top.p, event)) /* try original event */ 208 int tag = callbinTM(L, p1, p2, L->top.p, event); /* try original event */
204 return !l_isfalse(s2v(L->top.p)); 209 if (tag >= 0) /* found tag method? */
210 return !tagisfalse(tag);
205#if defined(LUA_COMPAT_LT_LE) 211#if defined(LUA_COMPAT_LT_LE)
206 else if (event == TM_LE) { 212 else if (event == TM_LE) {
207 /* try '!(p2 < p1)' for '(p1 <= p2)' */ 213 /* try '!(p2 < p1)' for '(p1 <= p2)' */
208 L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */ 214 L->ci->callstatus |= CIST_LEQ; /* mark it is doing 'lt' for 'le' */
209 if (callbinTM(L, p2, p1, L->top.p, TM_LT)) { 215 tag = callbinTM(L, p2, p1, L->top.p, TM_LT);
210 L->ci->callstatus ^= CIST_LEQ; /* clear mark */ 216 L->ci->callstatus ^= CIST_LEQ; /* clear mark */
211 return l_isfalse(s2v(L->top.p)); 217 if (tag >= 0) /* found tag method? */
212 } 218 return tagisfalse(tag);
213 /* else error will remove this 'ci'; no need to clear mark */
214 } 219 }
215#endif 220#endif
216 luaG_ordererror(L, p1, p2); /* no metamethod found */ 221 luaG_ordererror(L, p1, p2); /* no metamethod found */