diff --git a/decode.go b/decode.go index 7ced1c48..9bd0dddf 100644 --- a/decode.go +++ b/decode.go @@ -603,7 +603,20 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error { continue } newFieldValue := d.createDecodableValue(fieldValue.Type()) - if err := d.decodeValue(newFieldValue, src); err != nil { + err := d.decodeValue(newFieldValue, src) + + if d.disallowUnknownField { + var ufe *unknownFieldError + if xerrors.As(err, &ufe) { + err = nil + } + + if err = d.deleteStructKeys(fieldValue, unknownFields); err != nil { + return errors.Wrapf(err, "cannot delete struct keys") + } + } + + if err != nil { if foundErr != nil { continue } @@ -618,21 +631,10 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error { } foundErr = te continue - } - - if d.disallowUnknownField { - var ufe *unknownFieldError - if !xerrors.As(err, &ufe) { - foundErr = err - continue - } - - if err = d.deleteStructKeys(fieldValue, unknownFields); err != nil { - return errors.Wrapf(err, "cannot delete struct keys") - } } else { - continue + foundErr = err } + continue } d.setDefaultValueIfConflicted(newFieldValue, structFieldMap) fieldValue.Set(d.castToAssignableValue(newFieldValue, fieldValue.Type())) diff --git a/decode_test.go b/decode_test.go index e7e4360a..5c830c3c 100644 --- a/decode_test.go +++ b/decode_test.go @@ -1233,6 +1233,37 @@ b: 1 t.Fatalf("v.C should be 0, got %d", v.C) } }) + t.Run("list", func(t *testing.T) { + type C struct { + Child `yaml:",inline"` + } + + var v struct { + Children []C `yaml:"children"` + } + + yml := `--- +children: +- b: 1 +- b: 2 +` + + if err := yaml.NewDecoder(strings.NewReader(yml), yaml.DisallowUnknownField()).Decode(&v); err != nil { + t.Fatalf(`parsing should succeed: %s`, err) + } + + if len(v.Children) != 2 { + t.Fatalf(`len(v.Children) should be 2, got %d`, len(v.Children)) + } + + if v.Children[0].B != 1 { + t.Fatalf(`v.Children[0].B should be 1, got %d`, v.Children[0].B) + } + + if v.Children[1].B != 2 { + t.Fatalf(`v.Children[1].B should be 2, got %d`, v.Children[1].B) + } + }) } func TestDecoder_DefaultValues(t *testing.T) {