From c0e22be0391e0e6c79a538a755f9af3ccee6e1c7 Mon Sep 17 00:00:00 2001 From: Masaaki Goshima Date: Tue, 9 Jun 2020 10:36:35 +0900 Subject: [PATCH] Fix reflection error in deleteStructKeys --- decode.go | 7 +++---- decode_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/decode.go b/decode.go index 896d8a71..bbee6d07 100644 --- a/decode.go +++ b/decode.go @@ -361,8 +361,7 @@ func errDuplicateKey(msg string, tk *token.Token) *duplicateKeyError { return &duplicateKeyError{err: errors.ErrSyntax(msg, tk)} } -func (d *Decoder) deleteStructKeys(structValue reflect.Value, unknownFields map[string]ast.Node) error { - structType := structValue.Type() +func (d *Decoder) deleteStructKeys(structType reflect.Type, unknownFields map[string]ast.Node) error { if structType.Kind() == reflect.Ptr { structType = structType.Elem() } @@ -383,7 +382,7 @@ func (d *Decoder) deleteStructKeys(structValue reflect.Value, unknownFields map[ } if structField.IsInline { - d.deleteStructKeys(structValue.FieldByName(field.Name), unknownFields) + d.deleteStructKeys(field.Type, unknownFields) } else { delete(unknownFields, structField.RenderName) } @@ -785,7 +784,7 @@ func (d *Decoder) decodeStruct(dst reflect.Value, src ast.Node) error { err = nil } - if err = d.deleteStructKeys(fieldValue, unknownFields); err != nil { + if err = d.deleteStructKeys(fieldValue.Type(), unknownFields); err != nil { return errors.Wrapf(err, "cannot delete struct keys") } } diff --git a/decode_test.go b/decode_test.go index aacf6f19..ef995bb9 100644 --- a/decode_test.go +++ b/decode_test.go @@ -1323,6 +1323,32 @@ c: true if !v.C { t.Fatal("failed to decode with inline key") } + + t.Run("multiple inline with strict", func(t *testing.T) { + type Base struct { + A int + B string + } + type Base2 struct { + Base *Base `yaml:",inline"` + } + yml := `--- +a: 1 +b: hello +` + var v struct { + Base2 *Base2 `yaml:",inline"` + } + if err := yaml.NewDecoder(strings.NewReader(yml), yaml.Strict()).Decode(&v); err != nil { + t.Fatalf("%+v", err) + } + if v.Base2.Base.A != 1 { + t.Fatal("failed to decode with inline key") + } + if v.Base2.Base.B != "hello" { + t.Fatal("failed to decode with inline key") + } + }) } func TestDecoder_InlineAndConflictKey(t *testing.T) {