Skip to content

Commit

Permalink
accounts/abi: validate fieldnames, fixes #24930 (#24932)
Browse files Browse the repository at this point in the history
  • Loading branch information
holiman authored May 23, 2022
1 parent 59ac229 commit af02e97
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 0 deletions.
8 changes: 8 additions & 0 deletions accounts/abi/bind/base_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -488,3 +488,11 @@ func TestCall(t *testing.T) {
}
}
}

// TestCrashers contains some strings which previously caused the abi codec to crash.
func TestCrashers(t *testing.T) {
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"_1"}]}]}]`))
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"&"}]}]}]`))
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"----"}]}]}]`))
abi.JSON(strings.NewReader(`[{"inputs":[{"type":"tuple[]","components":[{"type":"bool","name":"foo.Bar"}]}]}]`))
}
32 changes: 32 additions & 0 deletions accounts/abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"regexp"
"strconv"
"strings"
"unicode"
"unicode/utf8"

"github.com/ethereum/go-ethereum/common"
)
Expand Down Expand Up @@ -173,6 +175,9 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
if err != nil {
return Type{}, err
}
if !isValidFieldName(fieldName) {
return Type{}, fmt.Errorf("field %d has invalid name", idx)
}
overloadedNames[fieldName] = fieldName
fields = append(fields, reflect.StructField{
Name: fieldName, // reflect.StructOf will panic for any exported field.
Expand Down Expand Up @@ -399,3 +404,30 @@ func getTypeSize(t Type) int {
}
return 32
}

// isLetter reports whether a given 'rune' is classified as a Letter.
// This method is copied from reflect/type.go
func isLetter(ch rune) bool {
return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8.RuneSelf && unicode.IsLetter(ch)
}

// isValidFieldName checks if a string is a valid (struct) field name or not.
//
// According to the language spec, a field name should be an identifier.
//
// identifier = letter { letter | unicode_digit } .
// letter = unicode_letter | "_" .
// This method is copied from reflect/type.go
func isValidFieldName(fieldName string) bool {
for i, c := range fieldName {
if i == 0 && !isLetter(c) {
return false
}

if !(isLetter(c) || unicode.IsDigit(c)) {
return false
}
}

return len(fieldName) > 0
}

0 comments on commit af02e97

Please sign in to comment.