Skip to content

Commit

Permalink
add notify uplimit (#1075)
Browse files Browse the repository at this point in the history
* add notify uplimit

* add test

* add valid test

* add desrializeStackItem test

* add map deserialize test
  • Loading branch information
lucas7788 authored and laizy committed Sep 20, 2019
1 parent 46a5bc9 commit 799c934
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 10 deletions.
30 changes: 24 additions & 6 deletions smartcontract/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,34 +30,51 @@ import (
// According item types convert to hex string value
// Now neovm support type contain: ByteArray/Integer/Boolean/Array/Struct/Interop/StackItems
const (
MAX_COUNT = 1024
MAX_COUNT = 1024
MAX_NOTIFY_LENGTH = 64 * 1024 //64kb
)

func ConvertNeoVmTypeHexString(item interface{}) (interface{}, error) {
var count int
return convertNeoVmTypeHexString(item, &count)
var length int
res, err := convertNeoVmTypeHexString(item, &count, &length)
if err != nil {
return nil, err
}
if length > MAX_NOTIFY_LENGTH {
return nil, errors.New("length over max parameters convert length")
}
return res, nil
}

func convertNeoVmTypeHexString(item interface{}, count *int) (interface{}, error) {
func convertNeoVmTypeHexString(item interface{}, count *int, length *int) (interface{}, error) {
if item == nil {
return nil, nil
}
if *count > MAX_COUNT {
return nil, errors.New("over max parameters convert length")
}
if *length > MAX_NOTIFY_LENGTH {
return nil, errors.New("length over max parameters convert length")
}
switch v := item.(type) {
case *types.ByteArray:
arr, _ := v.GetByteArray()
*length += len(arr)
return common.ToHexString(arr), nil
case *types.Integer:
i, _ := v.GetBigInteger()
if i.Sign() == 0 {
*length += 1
return common.ToHexString([]byte{0}), nil
} else {
return common.ToHexString(common.BigIntToNeoBytes(i)), nil
bs := common.BigIntToNeoBytes(i)
*length += len(bs)
return common.ToHexString(bs), nil
}
case *types.Boolean:
b, _ := v.GetBoolean()
*length += 1
if b {
return common.ToHexString([]byte{1}), nil
} else {
Expand All @@ -68,7 +85,7 @@ func convertNeoVmTypeHexString(item interface{}, count *int) (interface{}, error
ar, _ := v.GetArray()
for _, val := range ar {
*count++
cv, err := convertNeoVmTypeHexString(val, count)
cv, err := convertNeoVmTypeHexString(val, count, length)
if err != nil {
return nil, err
}
Expand All @@ -80,7 +97,7 @@ func convertNeoVmTypeHexString(item interface{}, count *int) (interface{}, error
ar, _ := v.GetStruct()
for _, val := range ar {
*count++
cv, err := convertNeoVmTypeHexString(val, count)
cv, err := convertNeoVmTypeHexString(val, count, length)
if err != nil {
return nil, err
}
Expand All @@ -89,6 +106,7 @@ func convertNeoVmTypeHexString(item interface{}, count *int) (interface{}, error
return arr, nil
case *types.Interop:
it, _ := v.GetInterface()
*length += len(it.ToArray())
return common.ToHexString(it.ToArray()), nil
default:
log.Error("[ConvertTypes] Invalid Types!")
Expand Down
44 changes: 44 additions & 0 deletions smartcontract/common/common_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

package common

import (
"github.com/ontio/ontology/vm/neovm/types"
"github.com/stretchr/testify/assert"
"testing"
)

func TestConvertNeoVmTypeHexString(t *testing.T) {
value := make([]types.StackItems, 0)
arr := types.NewArray(value)
bs := make([]byte, 0)
for i := 0; i < MAX_NOTIFY_LENGTH; i++ {
bs = append(bs, 1)
}
b := types.NewByteArray(bs)
arr.Add(b)
_, err := ConvertNeoVmTypeHexString(arr)
assert.Nil(t, err)

bs = append(bs, 1)
b = types.NewByteArray(bs)
arr.Add(b)
_, err = ConvertNeoVmTypeHexString(arr)
assert.NotNil(t, err)
}
17 changes: 13 additions & 4 deletions smartcontract/service/neovm/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -334,11 +334,17 @@ func serializeStackItem(item vmtypes.StackItems, w io.Writer) error {
}

func DeserializeStackItem(r io.Reader) (items vmtypes.StackItems, err error) {
return deserializeStackItem(r, 0)
}

func deserializeStackItem(r io.Reader, depth int) (items vmtypes.StackItems, err error) {
t, err := serialization.ReadByte(r)
if err != nil {
return nil, errors.NewErr("Deserialize error: " + err.Error())
}

if depth > scommon.MAX_COUNT {
return nil, errors.NewErr("Deserialize error: " + "depth over the uplimit")
}
switch t {
case vmtypes.ByteArrayType:
b, err := serialization.ReadVarBytes(r)
Expand Down Expand Up @@ -368,7 +374,7 @@ func DeserializeStackItem(r io.Reader) (items vmtypes.StackItems, err error) {

var arr []vmtypes.StackItems
for count > 0 {
item, err := DeserializeStackItem(r)
item, err := deserializeStackItem(r, depth+1)
if err != nil {
return nil, err
}
Expand All @@ -390,12 +396,15 @@ func DeserializeStackItem(r io.Reader) (items vmtypes.StackItems, err error) {

mp := vmtypes.NewMap()
for count > 0 {
key, err := DeserializeStackItem(r)
key, err := deserializeStackItem(r, depth+1)
if err != nil {
return nil, err
}
if key.IsMapKey() != true {
return nil, errors.NewErr("is not map key")
}

value, err := DeserializeStackItem(r)
value, err := deserializeStackItem(r, depth+1)
if err != nil {
return nil, err
}
Expand Down
39 changes: 39 additions & 0 deletions smartcontract/service/neovm/runtime_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"errors"
"github.com/ontio/ontology/account"
"github.com/ontio/ontology/smartcontract/common"
"github.com/ontio/ontology/vm/neovm"
"github.com/ontio/ontology/vm/neovm/types"
"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -56,6 +57,44 @@ func TestRuntimeDeserializeBigInteger(t *testing.T) {

}

func TestRuntimeDeserializeDepth(t *testing.T) {
bsTemp := make([]byte, 0)
for i := 0; i < common.MAX_COUNT; i++ {
bsTemp = append(bsTemp, []byte{types.ArrayType, 0x01}...)
}
bsTemp = append(bsTemp, types.ByteArrayType)
bsTemp = append(bsTemp, []byte{0x01, 0x01}...)
_, err := DeserializeStackItem(bytes.NewReader(bsTemp))
assert.Nil(t, err)

bsTempMap := make([]byte, 0)
for i := 0; i < common.MAX_COUNT; i++ {
bsTempMap = append(bsTempMap, []byte{types.MapType, 0x01, 0x01, types.ByteArrayType, 0x01, 0x01, types.MapType, 0x01}...)
}
_, err = DeserializeStackItem(bytes.NewReader(bsTempMap))
assert.Nil(t, err)
}

func TestRuntimeDeserializeDepthInvalid(t *testing.T) {
bsTemp := make([]byte, 0)
for i := 0; i < common.MAX_COUNT+1; i++ {
bsTemp = append(bsTemp, []byte{types.ArrayType, 0x01}...)
}
bsTemp = append(bsTemp, types.ByteArrayType)
bsTemp = append(bsTemp, []byte{0x01, 0x01}...)
_, err := DeserializeStackItem(bytes.NewReader(bsTemp))
assert.Equal(t, "Deserialize error: "+"depth over the uplimit", err.Error())

bsTempMap := make([]byte, 0)
for i := 0; i < common.MAX_COUNT+1; i++ {
bsTempMap = append(bsTempMap, []byte{types.MapType, 0x01, types.MapType, 0x01, types.MapType, 0x01}...)
}
bsTempMap = append(bsTempMap, types.ByteArrayType)
bsTempMap = append(bsTempMap, []byte{0x01, 0x01}...)
_, err = DeserializeStackItem(bytes.NewReader(bsTempMap))
assert.Equal(t, "Deserialize error: "+"depth over the uplimit", err.Error())
}

func TestArrayRef(t *testing.T) {
a := types.NewArray(nil)
b := types.NewArray([]types.StackItems{a})
Expand Down

0 comments on commit 799c934

Please sign in to comment.