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.
This commit is contained in:
Roman Khimov 2022-11-15 23:48:02 +03:00
parent e9407e2054
commit 90582faacd

View file

@ -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