diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-01-04 11:35:56 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2016-01-04 11:35:56 -0200 |
commit | 7cd7c2e0a1e947bbcb03da123b31f4f74b366020 (patch) | |
tree | cacf010ba234ea427be3320d0d13e4228bc5d816 | |
parent | 07cf8415e3197b9a8e0f46743f7f9adc8fe8a256 (diff) | |
download | lua-7cd7c2e0a1e947bbcb03da123b31f4f74b366020.tar.gz lua-7cd7c2e0a1e947bbcb03da123b31f4f74b366020.tar.bz2 lua-7cd7c2e0a1e947bbcb03da123b31f4f74b366020.zip |
Metatable may access its own dealocated field when
it has a self reference in __newindex.
-rw-r--r-- | bugs | 49 |
1 files changed, 48 insertions, 1 deletions
@@ -3465,7 +3465,7 @@ patch = [[ | |||
3465 | Bug{ | 3465 | Bug{ |
3466 | what = [['io.lines' does not check maximum number of options]], | 3466 | what = [['io.lines' does not check maximum number of options]], |
3467 | report = [[Patrick Donnell, 2015/07/10]], | 3467 | report = [[Patrick Donnell, 2015/07/10]], |
3468 | since = [[3.0]], | 3468 | since = [[5.3.0]], |
3469 | fix = nil, | 3469 | fix = nil, |
3470 | example = [[ | 3470 | example = [[ |
3471 | -- can segfault in some machines | 3471 | -- can segfault in some machines |
@@ -3495,6 +3495,53 @@ patch = [[ | |||
3495 | } | 3495 | } |
3496 | 3496 | ||
3497 | 3497 | ||
3498 | ----------------------------------------------------------------- | ||
3499 | -- Lua 5.3.2 | ||
3500 | |||
3501 | Bug{ | ||
3502 | what = [[Metatable may access its own dealocated field when | ||
3503 | it has a self reference in __newindex]], | ||
3504 | report = [[actboy168@gmail.com, 2016/01/01]], | ||
3505 | since = [[5.3.2]], | ||
3506 | fix = nil, | ||
3507 | example = [[ | ||
3508 | local mt = {} | ||
3509 | mt.__newindex = mt | ||
3510 | local t = setmetatable({}, mt) | ||
3511 | t[1] = 1 -- will segfault on some machines | ||
3512 | ]], | ||
3513 | patch = [[ | ||
3514 | --- lvm.c 2015/11/23 11:30:45 2.265 | ||
3515 | +++ lvm.c 2016/01/01 14:34:12 | ||
3516 | @@ -190,18 +190,19 @@ | ||
3517 | for (loop = 0; loop < MAXTAGLOOP; loop++) { | ||
3518 | const TValue *tm; | ||
3519 | if (oldval != NULL) { | ||
3520 | - lua_assert(ttistable(t) && ttisnil(oldval)); | ||
3521 | + Table *h = hvalue(t); /* save 't' table */ | ||
3522 | + lua_assert(ttisnil(oldval)); | ||
3523 | /* must check the metamethod */ | ||
3524 | - if ((tm = fasttm(L, hvalue(t)->metatable, TM_NEWINDEX)) == NULL && | ||
3525 | + if ((tm = fasttm(L, h->metatable, TM_NEWINDEX)) == NULL && | ||
3526 | /* no metamethod; is there a previous entry in the table? */ | ||
3527 | (oldval != luaO_nilobject || | ||
3528 | /* no previous entry; must create one. (The next test is | ||
3529 | always true; we only need the assignment.) */ | ||
3530 | - (oldval = luaH_newkey(L, hvalue(t), key), 1))) { | ||
3531 | + (oldval = luaH_newkey(L, h, key), 1))) { | ||
3532 | /* no metamethod and (now) there is an entry with given key */ | ||
3533 | setobj2t(L, cast(TValue *, oldval), val); | ||
3534 | - invalidateTMcache(hvalue(t)); | ||
3535 | - luaC_barrierback(L, hvalue(t), val); | ||
3536 | + invalidateTMcache(h); | ||
3537 | + luaC_barrierback(L, h, val); | ||
3538 | return; | ||
3539 | } | ||
3540 | /* else will try the metamethod */ | ||
3541 | ]] | ||
3542 | } | ||
3543 | |||
3544 | |||
3498 | --[=[ | 3545 | --[=[ |
3499 | Bug{ | 3546 | Bug{ |
3500 | what = [[ ]], | 3547 | what = [[ ]], |