diff --git a/smartcontract/service/neovm/native.go b/smartcontract/service/neovm/native.go index 4ab3d93949..8e6f3aa0b8 100644 --- a/smartcontract/service/neovm/native.go +++ b/smartcontract/service/neovm/native.go @@ -20,7 +20,9 @@ package neovm import ( "bytes" + "errors" "fmt" + "math/big" "reflect" "github.com/ontio/ontology/common" @@ -29,7 +31,6 @@ import ( "github.com/ontio/ontology/smartcontract/states" vm "github.com/ontio/ontology/vm/neovm" "github.com/ontio/ontology/vm/neovm/types" - "math/big" ) func NativeInvoke(service *NeoVmService, engine *vm.ExecutionEngine) error { @@ -92,6 +93,13 @@ func NativeInvoke(service *NeoVmService, engine *vm.ExecutionEngine) error { } func BuildParamToNative(bf *bytes.Buffer, item types.StackItems) error { + if CircularRefAndDepthDetection(item) { + return errors.New("invoke native circular reference!") + } + return buildParamToNative(bf, item) +} + +func buildParamToNative(bf *bytes.Buffer, item types.StackItems) error { switch item.(type) { case *types.ByteArray: a, _ := item.GetByteArray() @@ -114,14 +122,14 @@ func BuildParamToNative(bf *bytes.Buffer, item types.StackItems) error { return err } for _, v := range arr { - if err := BuildParamToNative(bf, v); err != nil { + if err := buildParamToNative(bf, v); err != nil { return err } } case *types.Struct: st, _ := item.GetStruct() for _, v := range st { - if err := BuildParamToNative(bf, v); err != nil { + if err := buildParamToNative(bf, v); err != nil { return err } } diff --git a/smartcontract/test/native_test.go b/smartcontract/test/native_test.go new file mode 100644 index 0000000000..2bb6bcdef8 --- /dev/null +++ b/smartcontract/test/native_test.go @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 The ontology Authors + * This file is part of The ontology library. + * + * The ontology is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The ontology is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The ontology. If not, see . + */ + +package test + +import ( + "github.com/ontio/ontology/common" + "github.com/ontio/ontology/smartcontract" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestBuildParamToNative(t *testing.T) { + code := `00c57676c84c0500000000004c1400000000000000000000000000000000000000060068164f6e746f6c6f67792e4e61746976652e496e766f6b65` + + hex, err := common.HexToBytes(code) + + if err != nil { + t.Fatal("hex to byte error:", err) + } + + config := &smartcontract.Config{ + Time: 10, + Height: 10, + Tx: nil, + } + //cache := storage.NewCloneCache(testBatch) + sc := smartcontract.SmartContract{ + Config: config, + Gas: 100000, + } + engine, err := sc.NewExecuteEngine(hex) + + _, err = engine.Invoke() + + assert.Error(t, err, "invoke smart contract err: [NeoVmService] service system call error!: [SystemCall] service execute error!: invoke native circular reference!") +}