bug: 'luaV_settable' may invalidate a reference to a table and try

to reuse it.
This commit is contained in:
Roberto Ierusalimschy 2009-07-01 17:31:25 -03:00
parent 88564c3aec
commit afb3f7e754
1 changed files with 6 additions and 3 deletions

9
lvm.c
View File

@ -1,5 +1,5 @@
/* /*
** $Id: lvm.c,v 2.92 2009/06/17 16:17:14 roberto Exp roberto $ ** $Id: lvm.c,v 2.93 2009/06/17 17:50:09 roberto Exp roberto $
** Lua virtual machine ** Lua virtual machine
** See Copyright Notice in lua.h ** See Copyright Notice in lua.h
*/ */
@ -115,7 +115,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
callTM(L, tm, t, key, val, 1); callTM(L, tm, t, key, val, 1);
return; return;
} }
t = tm; /* else repeat with `tm' */ t = tm; /* else repeat with 'tm' */
} }
luaG_runerror(L, "loop in gettable"); luaG_runerror(L, "loop in gettable");
} }
@ -123,6 +123,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) {
void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
int loop; int loop;
TValue temp;
for (loop = 0; loop < MAXTAGLOOP; loop++) { for (loop = 0; loop < MAXTAGLOOP; loop++) {
const TValue *tm; const TValue *tm;
if (ttistable(t)) { /* `t' is a table? */ if (ttistable(t)) { /* `t' is a table? */
@ -142,7 +143,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
callTM(L, tm, t, key, val, 0); callTM(L, tm, t, key, val, 0);
return; return;
} }
t = tm; /* else repeat with `tm' */ /* else repeat with 'tm' */
setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */
t = &temp;
} }
luaG_runerror(L, "loop in settable"); luaG_runerror(L, "loop in settable");
} }