From 90582faacd2b0355d17afc43c7a4e38562fea385 Mon Sep 17 00:00:00 2001 From: Roman Khimov Date: Tue, 15 Nov 2022 23:48:02 +0300 Subject: [PATCH] vm: save current stack slice when loading new context v.estack is used throughout the code to work with estack, while ctx.sc.estack is (theoretically) just a reference to it that is saved on script load and restored to v.estack on context unload. The problem is that v.estack can grow as we use it and can be reallocated away from its original slice (saved in the ctx.sc.estack), so either ctx.sc.estack should be a pointer or we need to ensure that it's correct when loading a new script. The second approach is a bit safer for now and it fixes #2798. --- pkg/vm/vm.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pkg/vm/vm.go b/pkg/vm/vm.go index 3a348d530..5e672ccd5 100644 --- a/pkg/vm/vm.go +++ b/pkg/vm/vm.go @@ -335,18 +335,19 @@ func (v *VM) loadScriptWithCallingHash(b []byte, exe *nef.File, caller util.Uint hash util.Uint160, f callflag.CallFlag, rvcount int, offset int, onContextUnload ContextUnloadCallback) { v.checkInvocationStackSize() ctx := NewContextWithParams(b, rvcount, offset) + parent := v.Context() + if parent != nil { + ctx.sc.callingContext = parent.sc + parent.sc.estack = v.estack + } if rvcount != -1 || v.estack.Len() != 0 { v.estack = subStack(v.estack) } - parent := v.Context() ctx.sc.estack = v.estack initStack(&ctx.tryStack, "exception", nil) ctx.sc.callFlag = f ctx.sc.scriptHash = hash ctx.sc.callingScriptHash = caller - if parent != nil { - ctx.sc.callingContext = parent.sc - } ctx.sc.NEF = exe if v.invTree != nil { curTree := v.invTree