From cac00a2e4975116e64a2112116dd429b8b0c86f6 Mon Sep 17 00:00:00 2001 From: laizy Date: Mon, 3 Jun 2019 19:48:26 +0800 Subject: [PATCH] fix opcode xtuck panic (#932) --- vm/neovm/func_flowcontrol.go | 2 +- vm/neovm/func_stack_test.go | 6 +++--- vm/neovm/func_validate.go | 15 ++++++++++++++- vm/neovm/stack.go | 4 ++-- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/vm/neovm/func_flowcontrol.go b/vm/neovm/func_flowcontrol.go index 344c510408..860994d404 100644 --- a/vm/neovm/func_flowcontrol.go +++ b/vm/neovm/func_flowcontrol.go @@ -78,7 +78,7 @@ func opDCALL(e *ExecutionEngine) (VMState, error) { return FAULT, errors.ERR_DCALL_OFFSET_ERROR } - if dest.Sign() < 0 || dest.Cmp(big.NewInt(int64(len(e.Context.Code)))) > 0 { + if dest.Sign() < 0 || dest.Cmp(big.NewInt(int64(len(e.Context.Code)))) >= 0 { return FAULT, errors.ERR_DCALL_OFFSET_ERROR } diff --git a/vm/neovm/func_stack_test.go b/vm/neovm/func_stack_test.go index 4e68eb3ec9..23842ada35 100644 --- a/vm/neovm/func_stack_test.go +++ b/vm/neovm/func_stack_test.go @@ -141,10 +141,10 @@ func TestOpXTuck(t *testing.T) { stack.Push(types.NewInteger(big.NewInt(8888))) stack.Push(types.NewInteger(big.NewInt(7777))) - stack.Push(NewStackItem(types.NewInteger(big.NewInt(2)))) + stack.Push(NewStackItem(types.NewInteger(big.NewInt(0)))) e.EvaluationStack = stack - opXSwap(&e) + opXTuck(&e) v1, err := stack.Peek(0).GetBigInteger() if err != nil { t.Fatal("NeoVM OpXTuck test failed.") @@ -156,7 +156,7 @@ func TestOpXTuck(t *testing.T) { e1 := v1.Int64() e2 := v2.Int64() - if stack.Count() != 3 || e1 != 9999 || e2 != 7777 { + if stack.Count() != 4 || e1 != 7777 || e2 != 8888 { t.Fatal("NeoVM OpXTuck test failed.") } } diff --git a/vm/neovm/func_validate.go b/vm/neovm/func_validate.go index 30487895ca..0ac3f61329 100644 --- a/vm/neovm/func_validate.go +++ b/vm/neovm/func_validate.go @@ -157,7 +157,20 @@ func validateXSwap(e *ExecutionEngine) error { } func validateXTuck(e *ExecutionEngine) error { - return validateOpStack(e, "[validateXTuck]") + total := EvaluationStackCount(e) + if total < 1 { + return errors.ERR_UNDER_STACK_LEN + } + index, err := PeekBigInteger(e) + if err != nil { + return err + } + count := big.NewInt(0) + if index.Sign() < 0 || count.Add(index, big.NewInt(1)).Cmp(big.NewInt(int64(total))) > 0 { + return errors.ERR_BAD_VALUE + } + + return nil } func validatePick(e *ExecutionEngine) error { diff --git a/vm/neovm/stack.go b/vm/neovm/stack.go index d4c0ce7297..3300e95bb5 100644 --- a/vm/neovm/stack.go +++ b/vm/neovm/stack.go @@ -47,8 +47,8 @@ func (r *RandomAccessStack) Insert(index int, t types.StackItems) { return } index = l - index - r.e = append(r.e, r.e[l-1]) - copy(r.e[index+1:l], r.e[index:]) + r.e = append(r.e, t) + copy(r.e[index+1:], r.e[index:]) r.e[index] = t }