From 3d62db4f34a5c5e84b4d373f49df3a566b316aec Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Thu, 16 Jul 2020 11:47:42 +0300 Subject: [PATCH] vm: clear altstack on CALL, fix #1158 neo-vm doesn't copy altstack on CALL, so it effectively is cleared. But we need to copy things back on return if there are any. --- pkg/vm/vm.go | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 0312f01a6..3276ae567 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -258,8 +258,9 @@ func (v *VM) Load(prog []byte) { func (v *VM) LoadScript(b []byte) { ctx := NewContext(b) ctx.estack = v.estack - ctx.astack = v.astack + ctx.astack = v.newItemStack("alt") v.istack.PushVal(ctx) + v.astack = ctx.astack } // loadScriptWithHash if similar to the LoadScript method, but it also loads @@ -1138,6 +1139,8 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro newCtx := ctx.Copy() newCtx.rvcount = -1 + newCtx.astack = v.newItemStack("alt") + v.astack = newCtx.astack v.istack.PushVal(newCtx) offset := v.getJumpOffset(newCtx, parameter, 0) @@ -1202,8 +1205,15 @@ func (v *VM) execute(ctx *Context, op opcode.Opcode, parameter []byte) (err erro newEstack.Push(elem) } v.estack = newEstack - v.astack = v.Context().astack } + newAstack := v.Context().astack + if rvcount == -1 && newAstack != oldCtx.astack { + for i := oldCtx.astack.Len(); i > 0; i-- { + elem := oldCtx.astack.RemoveAt(i - 1) + newAstack.Push(elem) + } + } + v.astack = newAstack case opcode.CHECKSIG, opcode.VERIFY: var hashToCheck []byte