Prevent Panics in Field Trie Helpers (#7613)

* add tests to prevent panics

* if > 0

* fix typ
This commit is contained in:
Raul Jordan 2020-10-23 16:41:45 -05:00 committed by GitHub
parent ff50ea2e0d
commit b1c047b9ee
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 72 additions and 20 deletions

View File

@ -49,6 +49,7 @@ go_test(
srcs = [ srcs = [
"field_trie_test.go", "field_trie_test.go",
"getters_test.go", "getters_test.go",
"helpers_test.go",
"references_test.go", "references_test.go",
"state_trie_test.go", "state_trie_test.go",
"types_test.go", "types_test.go",

View File

@ -1,6 +1,7 @@
package state package state
import ( import (
"fmt"
"reflect" "reflect"
"sync" "sync"
@ -180,18 +181,23 @@ func handleByteArrays(val [][]byte, indices []uint64, convertAll bool) ([][32]by
length = len(val) length = len(val)
} }
roots := make([][32]byte, 0, length) roots := make([][32]byte, 0, length)
rootCreater := func(input []byte) { rootCreator := func(input []byte) {
newRoot := bytesutil.ToBytes32(input) newRoot := bytesutil.ToBytes32(input)
roots = append(roots, newRoot) roots = append(roots, newRoot)
} }
if convertAll { if convertAll {
for i := range val { for i := range val {
rootCreater(val[i]) rootCreator(val[i])
} }
return roots, nil return roots, nil
} }
if len(val) > 0 {
for _, idx := range indices { for _, idx := range indices {
rootCreater(val[idx]) if idx > uint64(len(val))-1 {
return nil, fmt.Errorf("index %d greater than number of byte arrays %d", idx, len(val))
}
rootCreator(val[idx])
}
} }
return roots, nil return roots, nil
} }
@ -203,7 +209,7 @@ func handleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll boo
} }
roots := make([][32]byte, 0, length) roots := make([][32]byte, 0, length)
hasher := hashutil.CustomSHA256Hasher() hasher := hashutil.CustomSHA256Hasher()
rootCreater := func(input *ethpb.Eth1Data) error { rootCreator := func(input *ethpb.Eth1Data) error {
newRoot, err := stateutil.Eth1Root(hasher, input) newRoot, err := stateutil.Eth1Root(hasher, input)
if err != nil { if err != nil {
return err return err
@ -213,19 +219,24 @@ func handleEth1DataSlice(val []*ethpb.Eth1Data, indices []uint64, convertAll boo
} }
if convertAll { if convertAll {
for i := range val { for i := range val {
err := rootCreater(val[i]) err := rootCreator(val[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
return roots, nil return roots, nil
} }
if len(val) > 0 {
for _, idx := range indices { for _, idx := range indices {
err := rootCreater(val[idx]) if idx > uint64(len(val))-1 {
return nil, fmt.Errorf("index %d greater than number of items in eth1 data slice %d", idx, len(val))
}
err := rootCreator(val[idx])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
}
return roots, nil return roots, nil
} }
@ -236,7 +247,7 @@ func handleValidatorSlice(val []*ethpb.Validator, indices []uint64, convertAll b
} }
roots := make([][32]byte, 0, length) roots := make([][32]byte, 0, length)
hasher := hashutil.CustomSHA256Hasher() hasher := hashutil.CustomSHA256Hasher()
rootCreater := func(input *ethpb.Validator) error { rootCreator := func(input *ethpb.Validator) error {
newRoot, err := stateutil.ValidatorRoot(hasher, input) newRoot, err := stateutil.ValidatorRoot(hasher, input)
if err != nil { if err != nil {
return err return err
@ -246,19 +257,24 @@ func handleValidatorSlice(val []*ethpb.Validator, indices []uint64, convertAll b
} }
if convertAll { if convertAll {
for i := range val { for i := range val {
err := rootCreater(val[i]) err := rootCreator(val[i])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
return roots, nil return roots, nil
} }
if len(val) > 0 {
for _, idx := range indices { for _, idx := range indices {
err := rootCreater(val[idx]) if idx > uint64(len(val))-1 {
return nil, fmt.Errorf("index %d greater than number of validators %d", idx, len(val))
}
err := rootCreator(val[idx])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
}
return roots, nil return roots, nil
} }
@ -286,11 +302,16 @@ func handlePendingAttestation(val []*pb.PendingAttestation, indices []uint64, co
} }
return roots, nil return roots, nil
} }
if len(val) > 0 {
for _, idx := range indices { for _, idx := range indices {
if idx > uint64(len(val))-1 {
return nil, fmt.Errorf("index %d greater than number of pending attestations %d", idx, len(val))
}
err := rootCreator(val[idx]) err := rootCreator(val[idx])
if err != nil { if err != nil {
return nil, err return nil, err
} }
} }
}
return roots, nil return roots, nil
} }

View File

@ -0,0 +1,30 @@
package state
import (
"testing"
ethpb "github.com/prysmaticlabs/ethereumapis/eth/v1alpha1"
pb "github.com/prysmaticlabs/prysm/proto/beacon/p2p/v1"
"github.com/prysmaticlabs/prysm/shared/testutil/assert"
)
func Test_handleValidatorSlice_OutOfRange(t *testing.T) {
vals := make([]*ethpb.Validator, 1)
indices := []uint64{3}
_, err := handleValidatorSlice(vals, indices, false)
assert.ErrorContains(t, "index 3 greater than number of validators 1", err)
}
func Test_handlePendingAttestation_OutOfRange(t *testing.T) {
items := make([]*pb.PendingAttestation, 1)
indices := []uint64{3}
_, err := handlePendingAttestation(items, indices, false)
assert.ErrorContains(t, "index 3 greater than number of pending attestations 1", err)
}
func Test_handleEth1DataSlice_OutOfRange(t *testing.T) {
items := make([]*ethpb.Eth1Data, 1)
indices := []uint64{3}
_, err := handleEth1DataSlice(items, indices, false)
assert.ErrorContains(t, "index 3 greater than number of items in eth1 data slice 1", err)
}