From c0be2b2a99f959ba187dbcba3cd08638e7770004 Mon Sep 17 00:00:00 2001 From: Evgenii Stratonikov Date: Tue, 24 Sep 2019 16:16:24 +0300 Subject: [PATCH] vm: support Map in REMOVE --- pkg/vm/vm.go | 18 +++++++++++++----- pkg/vm/vm_test.go | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 584b7c14e..658b26bc9 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -766,23 +766,31 @@ func (v *VM) execute(ctx *Context, op Instruction) { } } case REMOVE: - key := int(v.estack.Pop().BigInt().Int64()) + key := v.estack.Pop() + validateMapKey(key) + elem := v.estack.Pop() switch t := elem.value.(type) { case *ArrayItem: a := t.value - if key < 0 || key >= len(a) { + k := int(key.BigInt().Int64()) + if k < 0 || k >= len(a) { panic("REMOVE: invalid index") } - a = append(a[:key], a[key+1:]...) + a = append(a[:k], a[k+1:]...) t.value = a case *StructItem: a := t.value - if key < 0 || key >= len(a) { + k := int(key.BigInt().Int64()) + if k < 0 || k >= len(a) { panic("REMOVE: invalid index") } - a = append(a[:key], a[key+1:]...) + a = append(a[:k], a[k+1:]...) t.value = a + case *MapItem: + m := t.value + k := toMapKey(key.value) + delete(m, k) default: panic("REMOVE: invalid type") } diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index ad5aa475d..f46ea67ff 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -1696,6 +1696,23 @@ func TestREMOVEGood(t *testing.T) { assert.Equal(t, makeStackItem(1), vm.estack.Pop().value) } +func TestREMOVEMap(t *testing.T) { + prog := makeProgram(REMOVE, PUSH5, HASKEY) + vm := load(prog) + + m := NewMapItem() + m.Add(makeStackItem(5), makeStackItem(3)) + m.Add(makeStackItem([]byte{0, 1}), makeStackItem([]byte{2, 3})) + vm.estack.Push(&Element{value: m}) + vm.estack.Push(&Element{value: m}) + vm.estack.PushVal(makeStackItem(5)) + + vm.Run() + assert.Equal(t, false, vm.HasFailed()) + assert.Equal(t, 1, vm.estack.Len()) + assert.Equal(t, makeStackItem(false), vm.estack.Pop().value) +} + func TestCHECKSIGNoArgs(t *testing.T) { prog := makeProgram(CHECKSIG) vm := load(prog)