diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-07-01 17:31:25 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2009-07-01 17:31:25 -0300 |
| commit | afb3f7e754bde70895d639ff2a2738409a51c60e (patch) | |
| tree | 06e3f4ecd8646b82241e98c76d885a339053dedc | |
| parent | 88564c3aec8122ce20bd257e01d4ab32c9663051 (diff) | |
| download | lua-afb3f7e754bde70895d639ff2a2738409a51c60e.tar.gz lua-afb3f7e754bde70895d639ff2a2738409a51c60e.tar.bz2 lua-afb3f7e754bde70895d639ff2a2738409a51c60e.zip | |
bug: 'luaV_settable' may invalidate a reference to a table and try
to reuse it.
| -rw-r--r-- | lvm.c | 9 |
1 files changed, 6 insertions, 3 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lvm.c,v 2.92 2009/06/17 16:17:14 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.93 2009/06/17 17:50:09 roberto Exp roberto $ |
| 3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -115,7 +115,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
| 115 | callTM(L, tm, t, key, val, 1); | 115 | callTM(L, tm, t, key, val, 1); |
| 116 | return; | 116 | return; |
| 117 | } | 117 | } |
| 118 | t = tm; /* else repeat with `tm' */ | 118 | t = tm; /* else repeat with 'tm' */ |
| 119 | } | 119 | } |
| 120 | luaG_runerror(L, "loop in gettable"); | 120 | luaG_runerror(L, "loop in gettable"); |
| 121 | } | 121 | } |
| @@ -123,6 +123,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
| 123 | 123 | ||
| 124 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | 124 | void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { |
| 125 | int loop; | 125 | int loop; |
| 126 | TValue temp; | ||
| 126 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | 127 | for (loop = 0; loop < MAXTAGLOOP; loop++) { |
| 127 | const TValue *tm; | 128 | const TValue *tm; |
| 128 | if (ttistable(t)) { /* `t' is a table? */ | 129 | if (ttistable(t)) { /* `t' is a table? */ |
| @@ -142,7 +143,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { | |||
| 142 | callTM(L, tm, t, key, val, 0); | 143 | callTM(L, tm, t, key, val, 0); |
| 143 | return; | 144 | return; |
| 144 | } | 145 | } |
| 145 | t = tm; /* else repeat with `tm' */ | 146 | /* else repeat with 'tm' */ |
| 147 | setobj(L, &temp, tm); /* avoid pointing inside table (may rehash) */ | ||
| 148 | t = &temp; | ||
| 146 | } | 149 | } |
| 147 | luaG_runerror(L, "loop in settable"); | 150 | luaG_runerror(L, "loop in settable"); |
| 148 | } | 151 | } |
