vm: allow big string keys in PICKITEM

Because `MaxKeySize` is bigger than integer size, we fail on integer
cast while retreiving items from map. SETITEM is not affected.

Signed-off-by: Evgeniy Stratonikov <evgeniy@nspcc.ru>
This commit is contained in:
Evgeniy Stratonikov 2021-10-08 15:05:36 +03:00
parent fa2ca3f25a
commit 435463e620
2 changed files with 12 additions and 1 deletions

View file

@ -1087,11 +1087,11 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
validateMapKey(key) validateMapKey(key)
obj := v.estack.Pop() obj := v.estack.Pop()
index := int(key.BigInt().Int64())
switch t := obj.value.(type) { switch t := obj.value.(type) {
// Struct and Array items have their underlying value as []Item. // Struct and Array items have their underlying value as []Item.
case *stackitem.Array, *stackitem.Struct: case *stackitem.Array, *stackitem.Struct:
index := int(key.BigInt().Int64())
arr := t.Value().([]stackitem.Item) arr := t.Value().([]stackitem.Item)
if index < 0 || index >= len(arr) { if index < 0 || index >= len(arr) {
panic("PICKITEM: invalid index") panic("PICKITEM: invalid index")
@ -1105,6 +1105,7 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
} }
v.estack.PushItem(t.Value().([]stackitem.MapElement)[index].Value.Dup()) v.estack.PushItem(t.Value().([]stackitem.MapElement)[index].Value.Dup())
default: default:
index := int(key.BigInt().Int64())
arr := obj.Bytes() arr := obj.Bytes()
if index < 0 || index >= len(arr) { if index < 0 || index >= len(arr) {
panic("PICKITEM: invalid index") panic("PICKITEM: invalid index")

View file

@ -1205,6 +1205,16 @@ func TestSETITEMMap(t *testing.T) {
m := stackitem.NewMap() m := stackitem.NewMap()
m.Add(stackitem.Make(5), stackitem.Make(3)) m.Add(stackitem.Make(5), stackitem.Make(3))
runWithArgs(t, prog, []byte{0, 1}, m, 5, m, 5, []byte{0, 1}) runWithArgs(t, prog, []byte{0, 1}, m, 5, m, 5, []byte{0, 1})
t.Run("big key", func(t *testing.T) {
m := stackitem.NewMap()
key := make([]byte, stackitem.MaxKeySize)
for i := range key {
key[i] = 0x0F
}
m.Add(stackitem.NewByteArray(key), stackitem.Make(3))
runWithArgs(t, prog, "value", m, key, m, key, "value")
})
} }
func TestSETITEMBigMapBad(t *testing.T) { func TestSETITEMBigMapBad(t *testing.T) {