From fca11a621ef57b1b90eb45e88d4f88d300783850 Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Mon, 11 Dec 2023 14:07:54 -0500 Subject: [PATCH 1/2] Fix unmarshaling of nested non-exported struct Fixes #915 --- unmarshaler.go | 2 +- unmarshaler_test.go | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/unmarshaler.go b/unmarshaler.go index 868c74c1..36d2783e 100644 --- a/unmarshaler.go +++ b/unmarshaler.go @@ -1097,7 +1097,7 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node f := fieldByIndex(v, path) - if !f.CanSet() { + if !f.CanAddr() { // If the field is not settable, need to take a slower path and make a copy of // the struct itself to a new location. nvp := reflect.New(v.Type()) diff --git a/unmarshaler_test.go b/unmarshaler_test.go index 40192683..fa015c2e 100644 --- a/unmarshaler_test.go +++ b/unmarshaler_test.go @@ -2801,6 +2801,28 @@ res = [ } } +func TestIssue915(t *testing.T) { + type blah struct { + A string `toml:"a"` + } + + type config struct { + Fizz string `toml:"fizz"` + blah `toml:"blah"` + } + + b := []byte(` +fizz = "abc" +blah.a = "def"`) + var cfg config + err := toml.Unmarshal(b, &cfg) + require.NoError(t, err) + + require.Equal(t, "abc", cfg.Fizz) + require.Equal(t, "def", cfg.blah.A) + require.Equal(t, "def", cfg.A) +} + func TestUnmarshalDecodeErrors(t *testing.T) { examples := []struct { desc string From a8ed6d35547ce0eef40d6f31f2971b9a4cb4e0fa Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Mon, 11 Dec 2023 14:10:06 -0500 Subject: [PATCH 2/2] Fix comment --- unmarshaler.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/unmarshaler.go b/unmarshaler.go index 36d2783e..c5e5f339 100644 --- a/unmarshaler.go +++ b/unmarshaler.go @@ -1098,8 +1098,8 @@ func (d *decoder) handleKeyValuePart(key unstable.Iterator, value *unstable.Node f := fieldByIndex(v, path) if !f.CanAddr() { - // If the field is not settable, need to take a slower path and make a copy of - // the struct itself to a new location. + // If the field is not addressable, need to take a slower path and + // make a copy of the struct itself to a new location. nvp := reflect.New(v.Type()) nvp.Elem().Set(v) v = nvp.Elem()