@@ -23,6 +23,8 @@ import (
23
23
"regexp"
24
24
"strconv"
25
25
"strings"
26
+ "unicode"
27
+ "unicode/utf8"
26
28
27
29
"github.com/XinFinOrg/XDPoSChain/common"
28
30
)
@@ -172,6 +174,9 @@ func NewType(t string, internalType string, components []ArgumentMarshaling) (ty
172
174
if err != nil {
173
175
return Type {}, err
174
176
}
177
+ if ! isValidFieldName (fieldName ) {
178
+ return Type {}, fmt .Errorf ("field %d has invalid name" , idx )
179
+ }
175
180
overloadedNames [fieldName ] = fieldName
176
181
fields = append (fields , reflect.StructField {
177
182
Name : fieldName , // reflect.StructOf will panic for any exported field.
@@ -398,3 +403,30 @@ func getTypeSize(t Type) int {
398
403
}
399
404
return 32
400
405
}
406
+
407
+ // isLetter reports whether a given 'rune' is classified as a Letter.
408
+ // This method is copied from reflect/type.go
409
+ func isLetter (ch rune ) bool {
410
+ return 'a' <= ch && ch <= 'z' || 'A' <= ch && ch <= 'Z' || ch == '_' || ch >= utf8 .RuneSelf && unicode .IsLetter (ch )
411
+ }
412
+
413
+ // isValidFieldName checks if a string is a valid (struct) field name or not.
414
+ //
415
+ // According to the language spec, a field name should be an identifier.
416
+ //
417
+ // identifier = letter { letter | unicode_digit } .
418
+ // letter = unicode_letter | "_" .
419
+ // This method is copied from reflect/type.go
420
+ func isValidFieldName (fieldName string ) bool {
421
+ for i , c := range fieldName {
422
+ if i == 0 && ! isLetter (c ) {
423
+ return false
424
+ }
425
+
426
+ if ! (isLetter (c ) || unicode .IsDigit (c )) {
427
+ return false
428
+ }
429
+ }
430
+
431
+ return len (fieldName ) > 0
432
+ }
0 commit comments