summaryrefslogtreecommitdiffstats
path: root/patches/lua-5.1.4/0004-luaV_settable-may-invalidate-a-reference-to-a-table-.patch
blob: fe118921e001086151bd07b8b781dc1de9a39427 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
From: =?UTF-8?q?Beno=C3=AEt=20Burnichon?= <benoit.burnichon@airtag.com>
Date: Tue, 6 Dec 2011 14:13:59 +0100
Subject: [PATCH] luaV_settable may invalidate a reference to a table and try
 to reuse it
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Comes from http://www.lua.org/bugs.html#5.1.4-4

reported by Mark Feldman on 27 Jun 2009.
Example:
 --
 grandparent = {}
 grandparent.__newindex = function(s,_,_) print(s) end

 parent = {}
 parent.__newindex = parent
 setmetatable(parent, grandparent)

 child = setmetatable({}, parent)
 child.foo = 10      --> (crash on some machines)
 --

Signed-off-by: Benoît Burnichon <benoit.burnichon@airtag.com>
---
 src/lvm.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

diff --git a/src/lvm.c b/src/lvm.c
index ee3256a..4ac2e71 100644
--- a/src/lvm.c
+++ b/src/lvm.c
@@ -133,6 +133,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) {
   int loop;
+  TValue temp;
   for (loop = 0; loop < MAXTAGLOOP; loop++) {
     const TValue *tm;
     if (ttistable(t)) {  /* `t' is a table? */
@@ -152,7 +153,9 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) {
       callTM(L, tm, t, key, val);
       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");
 }