Merge pull request #973 from nspcc-dev/fix/refcount

vm: update stack size in SETITEM properly
This commit is contained in:
Roman Khimov 2020-05-21 16:47:27 +03:00 committed by GitHub
commit e07fd4f9f0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 22 additions and 2 deletions

View file

@ -1051,8 +1051,8 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
arr[index] = item arr[index] = item
v.estack.updateSizeAdd(arr[index]) v.estack.updateSizeAdd(arr[index])
case *MapItem: case *MapItem:
if t.Has(key.value) { if i := t.Index(key.value); i >= 0 {
v.estack.updateSizeRemove(item) v.estack.updateSizeRemove(t.value[i].Value)
} else if len(t.value) >= MaxArraySize { } else if len(t.value) >= MaxArraySize {
panic("too big map") panic("too big map")
} }

View file

@ -1442,6 +1442,26 @@ func TestSETITEMBigMapBad(t *testing.T) {
checkVMFailed(t, vm) checkVMFailed(t, vm)
} }
// This test checks is SETITEM properly updates reference counter.
// 1. Create 2 arrays of size MaxArraySize - 3. (MaxStackSize = 2 * MaxArraySize)
// 2. SETITEM each of them to a map.
// 3. Replace each of them with a scalar value.
func TestSETITEMMapStackLimit(t *testing.T) {
size := MaxArraySize - 3
m := NewMapItem()
m.Add(NewBigIntegerItem(1), NewArrayItem(makeArrayOfFalses(size)))
m.Add(NewBigIntegerItem(2), NewArrayItem(makeArrayOfFalses(size)))
prog := makeProgram(
opcode.DUP, opcode.PUSH1, opcode.PUSH1, opcode.SETITEM,
opcode.DUP, opcode.PUSH2, opcode.PUSH2, opcode.SETITEM,
opcode.DUP, opcode.PUSH3, opcode.PUSH3, opcode.SETITEM,
opcode.DUP, opcode.PUSH4, opcode.PUSH4, opcode.SETITEM)
v := load(prog)
v.estack.PushVal(m)
runVM(t, v)
}
func TestSETITEMBigMapGood(t *testing.T) { func TestSETITEMBigMapGood(t *testing.T) {
prog := makeProgram(opcode.SETITEM) prog := makeProgram(opcode.SETITEM)
vm := load(prog) vm := load(prog)