commit 7cd7c2e0a1e947bbcb03da123b31f4f74b366020
parent 07cf8415e3197b9a8e0f46743f7f9adc8fe8a256
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 4 Jan 2016 11:35:30 -0200
Metatable may access its own dealocated field when
it has a self reference in __newindex.
Diffstat:
M | bugs | | | 49 | ++++++++++++++++++++++++++++++++++++++++++++++++- |
1 file changed, 48 insertions(+), 1 deletion(-)
diff --git a/bugs b/bugs
@@ -3465,7 +3465,7 @@ patch = [[
Bug{
what = [['io.lines' does not check maximum number of options]],
report = [[Patrick Donnell, 2015/07/10]],
-since = [[3.0]],
+since = [[5.3.0]],
fix = nil,
example = [[
-- can segfault in some machines
@@ -3495,6 +3495,53 @@ patch = [[
}
+-----------------------------------------------------------------
+-- Lua 5.3.2
+
+Bug{
+what = [[Metatable may access its own dealocated field when
+it has a self reference in __newindex]],
+report = [[actboy168@gmail.com, 2016/01/01]],
+since = [[5.3.2]],
+fix = nil,
+example = [[
+local mt = {}
+mt.__newindex = mt
+local t = setmetatable({}, mt)
+t[1] = 1 -- will segfault on some machines
+]],
+patch = [[
+--- lvm.c 2015/11/23 11:30:45 2.265
++++ lvm.c 2016/01/01 14:34:12
+@@ -190,18 +190,19 @@
+ for (loop = 0; loop < MAXTAGLOOP; loop++) {
+ const TValue *tm;
+ if (oldval != NULL) {
+- lua_assert(ttistable(t) && ttisnil(oldval));
++ Table *h = hvalue(t); /* save 't' table */
++ lua_assert(ttisnil(oldval));
+ /* must check the metamethod */
+- if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL &&
++ if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL &&
+ /* no metamethod; is there a previous entry in the table? */
+ (oldval != luaO_nilobject ||
+ /* no previous entry; must create one. (The next test is
+ always true; we only need the assignment.) */
+- (oldval = luaH_newkey(L, hvalue(t), key), 1))) {
++ (oldval = luaH_newkey(L, h, key), 1))) {
+ /* no metamethod and (now) there is an entry with given key */
+ setobj2t(L, cast(TValue *, oldval), val);
+- invalidateTMcache(hvalue(t));
+- luaC_barrierback(L, hvalue(t), val);
++ invalidateTMcache(h);
++ luaC_barrierback(L, h, val);
+ return;
+ }
+ /* else will try the metamethod */
+]]
+}
+
+
--[=[
Bug{
what = [[ ]],