From 70c03aedf4e0a79e5e920577b4e85968024efd5d Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Mon, 15 Aug 2022 16:18:01 -0400 Subject: [PATCH 1/2] Decode: error on array table mismatched type Prevent the decoder from continuing if it encounters a type it cannot decode an array table into. Fixes #799 --- unmarshaler.go | 4 ++-- unmarshaler_test.go | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/unmarshaler.go b/unmarshaler.go index 24673f72..6f196e41 100644 --- a/unmarshaler.go +++ b/unmarshaler.go @@ -344,9 +344,9 @@ func (d *decoder) handleArrayTableCollectionLast(key ast.Iterator, v reflect.Val elem := v.Index(idx) _, err := d.handleArrayTable(key, elem) return v, err + default: + return reflect.Value{}, fmt.Errorf("toml: cannot decode array table into a %s", v.Type()) } - - return d.handleArrayTable(key, v) } // When parsing an array table expression, each part of the key needs to be diff --git a/unmarshaler_test.go b/unmarshaler_test.go index 83f00aab..8b0cc5f2 100644 --- a/unmarshaler_test.go +++ b/unmarshaler_test.go @@ -2413,6 +2413,22 @@ Host = 'main.domain.com' require.Equal(t, expected, string(b)) } +func TestIssue799(t *testing.T) { + const testTOML = ` +# notice the double brackets +[[test]] +answer = 42 +` + + var s struct { + // should be []map[string]int + Test map[string]int `toml:"test"` + } + + err := toml.Unmarshal([]byte(testTOML), &s) + require.Error(t, err) +} + func TestUnmarshalDecodeErrors(t *testing.T) { examples := []struct { desc string From 015e340c0ef721cba643f8168b174d0151ab40f6 Mon Sep 17 00:00:00 2001 From: Thomas Pelletier Date: Mon, 15 Aug 2022 16:35:07 -0400 Subject: [PATCH 2/2] Add tests for handleKeyValuePart --- unmarshaler_test.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/unmarshaler_test.go b/unmarshaler_test.go index 8b0cc5f2..def64348 100644 --- a/unmarshaler_test.go +++ b/unmarshaler_test.go @@ -1735,6 +1735,28 @@ B = "data"`, } }, }, + { + desc: "kv that points to a slice", + input: "a.b.c = 'foo'", + gen: func() test { + doc := map[string][]string{} + return test{ + target: &doc, + err: true, + } + }, + }, + { + desc: "kv that points to a pointer to a slice", + input: "a.b.c = 'foo'", + gen: func() test { + doc := map[string]*[]string{} + return test{ + target: &doc, + err: true, + } + }, + }, } for _, e := range examples {