vm: allow Null arguments for LT,LE,GT,GE opcodes

This commit is contained in:
Evgeniy Stratonikov 2021-04-29 14:34:52 +03:00
parent dc393642a2
commit 8fa4a576f4
2 changed files with 32 additions and 18 deletions

View file

@ -972,25 +972,27 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro
a := v.estack.Pop().BigInt() a := v.estack.Pop().BigInt()
v.estack.PushVal(a.Cmp(b) != 0) v.estack.PushVal(a.Cmp(b) != 0)
case opcode.LT: case opcode.LT, opcode.LE, opcode.GT, opcode.GE:
b := v.estack.Pop().BigInt() eb := v.estack.Pop()
a := v.estack.Pop().BigInt() ea := v.estack.Pop()
v.estack.PushVal(a.Cmp(b) == -1) _, aNil := ea.Item().(stackitem.Null)
_, bNil := eb.Item().(stackitem.Null)
case opcode.LE: res := !aNil && !bNil
b := v.estack.Pop().BigInt() if res {
a := v.estack.Pop().BigInt() cmp := ea.BigInt().Cmp(eb.BigInt())
v.estack.PushVal(a.Cmp(b) <= 0) switch op {
case opcode.LT:
case opcode.GT: res = cmp == -1
b := v.estack.Pop().BigInt() case opcode.LE:
a := v.estack.Pop().BigInt() res = cmp <= 0
v.estack.PushVal(a.Cmp(b) == 1) case opcode.GT:
res = cmp == 1
case opcode.GE: case opcode.GE:
b := v.estack.Pop().BigInt() res = cmp >= 0
a := v.estack.Pop().BigInt() }
v.estack.PushVal(a.Cmp(b) >= 0) }
v.estack.PushVal(res)
case opcode.MIN: case opcode.MIN:
b := v.estack.Pop().BigInt() b := v.estack.Pop().BigInt()

View file

@ -807,6 +807,18 @@ func TestSHL(t *testing.T) {
t.Run("BigResult", getTestFuncForVM(prog, nil, getBigInt(stackitem.MaxBigIntegerSizeBits/2, 0), stackitem.MaxBigIntegerSizeBits/2)) t.Run("BigResult", getTestFuncForVM(prog, nil, getBigInt(stackitem.MaxBigIntegerSizeBits/2, 0), stackitem.MaxBigIntegerSizeBits/2))
} }
func TestArithNullArg(t *testing.T) {
for _, op := range []opcode.Opcode{opcode.LT, opcode.LE, opcode.GT, opcode.GE} {
prog := makeProgram(op)
t.Run(op.String(), func(t *testing.T) {
runWithArgs(t, prog, false, stackitem.Null{}, 0)
runWithArgs(t, prog, false, 0, stackitem.Null{})
runWithArgs(t, prog, nil, stackitem.NewInterop(nil), 1) // also has `.Value() == nil`
})
}
}
func TestLT(t *testing.T) { func TestLT(t *testing.T) {
prog := makeProgram(opcode.LT) prog := makeProgram(opcode.LT)
runWithArgs(t, prog, false, 4, 3) runWithArgs(t, prog, false, 4, 3)