diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 94912eda1..6bb1efe39 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -691,7 +691,12 @@ func (v *VM) execute(ctx *Context, op Instruction) { item := arr[index] v.estack.PushVal(item) default: - panic("PICKITEM: unknown type") + arr := obj.Bytes() + if index < 0 || index >= len(arr) { + panic("PICKITEM: invalid index") + } + item := arr[index] + v.estack.PushVal(int(item)) } case SETITEM: diff --git a/pkg/vm/vm_test.go b/pkg/vm/vm_test.go index b85f4bc0c..c45c2f0cb 100644 --- a/pkg/vm/vm_test.go +++ b/pkg/vm/vm_test.go @@ -514,6 +514,37 @@ func TestAPPENDWrongType(t *testing.T) { assert.Equal(t, true, vm.state.HasFlag(faultState)) } +func TestPICKITEMBadIndex(t *testing.T) { + prog := makeProgram(PICKITEM) + vm := load(prog) + vm.estack.PushVal([]StackItem{}) + vm.estack.PushVal(0) + vm.Run() + assert.Equal(t, true, vm.state.HasFlag(faultState)) +} + +func TestPICKITEMArray(t *testing.T) { + prog := makeProgram(PICKITEM) + vm := load(prog) + vm.estack.PushVal([]StackItem{makeStackItem(1), makeStackItem(2)}) + vm.estack.PushVal(1) + vm.Run() + assert.Equal(t, false, vm.state.HasFlag(faultState)) + assert.Equal(t, 1, vm.estack.Len()) + assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) +} + +func TestPICKITEMByteArray(t *testing.T) { + prog := makeProgram(PICKITEM) + vm := load(prog) + vm.estack.PushVal([]byte{1, 2}) + vm.estack.PushVal(1) + vm.Run() + assert.Equal(t, false, vm.state.HasFlag(faultState)) + assert.Equal(t, 1, vm.estack.Len()) + assert.Equal(t, makeStackItem(2), vm.estack.Pop().value) +} + func TestSIGNNoArgument(t *testing.T) { prog := makeProgram(SIGN) vm := load(prog)