mirror of
https://github.com/nspcc-dev/neo-go.git
synced 2024-11-26 19:42:23 +00:00
vm: isolate stack in LoadScript
When calling contract it must be provided with a new stack containing only it's arguments. The result is then copied back on RET. Fix #1220.
This commit is contained in:
parent
13b9eda08d
commit
466af55dea
2 changed files with 17 additions and 0 deletions
|
@ -329,6 +329,7 @@ func getTestContractState() *state.Contract {
|
||||||
byte(opcode.ABORT), // abort if no offset was provided
|
byte(opcode.ABORT), // abort if no offset was provided
|
||||||
byte(opcode.ADD), byte(opcode.RET),
|
byte(opcode.ADD), byte(opcode.RET),
|
||||||
byte(opcode.PUSH7), byte(opcode.RET),
|
byte(opcode.PUSH7), byte(opcode.RET),
|
||||||
|
byte(opcode.DROP), byte(opcode.RET),
|
||||||
}
|
}
|
||||||
h := hash.Hash160(script)
|
h := hash.Hash160(script)
|
||||||
m := manifest.NewManifest(h)
|
m := manifest.NewManifest(h)
|
||||||
|
@ -348,6 +349,11 @@ func getTestContractState() *state.Contract {
|
||||||
Parameters: []manifest.Parameter{},
|
Parameters: []manifest.Parameter{},
|
||||||
ReturnType: smartcontract.IntegerType,
|
ReturnType: smartcontract.IntegerType,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: "drop",
|
||||||
|
Offset: 5,
|
||||||
|
ReturnType: smartcontract.VoidType,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
return &state.Contract{
|
return &state.Contract{
|
||||||
Script: script,
|
Script: script,
|
||||||
|
@ -375,6 +381,7 @@ func TestContractCall(t *testing.T) {
|
||||||
m := manifest.NewManifest(hash.Hash160(currScript))
|
m := manifest.NewManifest(hash.Hash160(currScript))
|
||||||
perm := manifest.NewPermission(manifest.PermissionHash, h)
|
perm := manifest.NewPermission(manifest.PermissionHash, h)
|
||||||
perm.Methods.Add("add")
|
perm.Methods.Add("add")
|
||||||
|
perm.Methods.Add("drop")
|
||||||
m.Permissions = append(m.Permissions, *perm)
|
m.Permissions = append(m.Permissions, *perm)
|
||||||
|
|
||||||
require.NoError(t, ic.DAO.PutContractState(&state.Contract{
|
require.NoError(t, ic.DAO.PutContractState(&state.Contract{
|
||||||
|
@ -425,6 +432,15 @@ func TestContractCall(t *testing.T) {
|
||||||
t.Run("NotEnoughArguments", runInvalid(
|
t.Run("NotEnoughArguments", runInvalid(
|
||||||
stackitem.NewArray([]stackitem.Item{stackitem.Make(1)}), "add", h.BytesBE()))
|
stackitem.NewArray([]stackitem.Item{stackitem.Make(1)}), "add", h.BytesBE()))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
t.Run("IsolatedStack", func(t *testing.T) {
|
||||||
|
initVM(v)
|
||||||
|
v.Estack().PushVal(stackitem.NewArray(nil))
|
||||||
|
v.Estack().PushVal("drop")
|
||||||
|
v.Estack().PushVal(h.BytesBE())
|
||||||
|
require.NoError(t, contractCall(ic, v))
|
||||||
|
require.Error(t, v.Run())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestContractCreate(t *testing.T) {
|
func TestContractCreate(t *testing.T) {
|
||||||
|
|
|
@ -279,6 +279,7 @@ func (v *VM) LoadScript(b []byte) {
|
||||||
// LoadScriptWithFlags loads script and sets call flag to f.
|
// LoadScriptWithFlags loads script and sets call flag to f.
|
||||||
func (v *VM) LoadScriptWithFlags(b []byte, f smartcontract.CallFlag) {
|
func (v *VM) LoadScriptWithFlags(b []byte, f smartcontract.CallFlag) {
|
||||||
ctx := NewContext(b)
|
ctx := NewContext(b)
|
||||||
|
v.estack = v.newItemStack("estack")
|
||||||
ctx.estack = v.estack
|
ctx.estack = v.estack
|
||||||
ctx.tryStack = NewStack("exception")
|
ctx.tryStack = NewStack("exception")
|
||||||
ctx.callFlag = f
|
ctx.callFlag = f
|
||||||
|
|
Loading…
Reference in a new issue