lang: Prevent struct types with duplicate fields
Struct types with duplicate fields are invalid types and weren't caught by the parser. This fixes the issue and adds some associated tests. It also checks and tests for duplicate struct value field names. As a technical side-note, this doesn't change the lang/types/ functions to remove panics-- the signatures are simplified to make their use simple, and we intentionally panic if they're used incorrectly. In this case, one was being used without having previously validated the input. Thanks to Patrick Meyer for finding this issue via fuzzing!
This commit is contained in:
@@ -5730,6 +5730,7 @@ func (obj *ExprMap) Apply(fn func(interfaces.Node) error) error {
|
||||
// Init initializes this branch of the AST, and returns an error if it fails to
|
||||
// validate.
|
||||
func (obj *ExprMap) Init(data *interfaces.Data) error {
|
||||
// XXX: Can we check that there aren't any duplicate keys? Can we Cmp?
|
||||
for _, x := range obj.KVs {
|
||||
if err := x.Key.Init(data); err != nil {
|
||||
return err
|
||||
@@ -6252,7 +6253,14 @@ func (obj *ExprStruct) Apply(fn func(interfaces.Node) error) error {
|
||||
// Init initializes this branch of the AST, and returns an error if it fails to
|
||||
// validate.
|
||||
func (obj *ExprStruct) Init(data *interfaces.Data) error {
|
||||
fields := make(map[string]struct{})
|
||||
for _, x := range obj.Fields {
|
||||
// Validate field names and ensure no duplicates!
|
||||
if _, exists := fields[x.Name]; exists {
|
||||
return fmt.Errorf("duplicate struct field name of: `%s`", x.Name)
|
||||
}
|
||||
fields[x.Name] = struct{}{}
|
||||
|
||||
if err := x.Value.Init(data); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user