diff --git a/internal/ast/ast.go b/internal/ast/ast.go index 82c1cb9..3b86002 100644 --- a/internal/ast/ast.go +++ b/internal/ast/ast.go @@ -136,7 +136,6 @@ func (n *Node) Key() Iterator { // Guaranteed to be non-nil. // Panics if not called on a KeyValue node, or if the Children are malformed. func (n *Node) Value() *Node { - assertKind(KeyValue, *n) return n.Child() } @@ -144,9 +143,3 @@ func (n *Node) Value() *Node { func (n *Node) Children() Iterator { return Iterator{node: n.Child()} } - -func assertKind(k Kind, n Node) { - if n.Kind != k { - panic(fmt.Errorf("method was expecting a %s, not a %s", k, n.Kind)) - } -} diff --git a/internal/tracker/seen.go b/internal/tracker/seen.go index 8adc4dc..1d7874b 100644 --- a/internal/tracker/seen.go +++ b/internal/tracker/seen.go @@ -232,9 +232,14 @@ func (s *SeenTracker) checkKeyValue(parentIdx int, node *ast.Node) error { kind := valueKind var err error - if node.Value().Kind == ast.InlineTable { + value := node.Value() + + switch value.Kind { + case ast.InlineTable: kind = tableKind - err = s.checkInlineTable(parentIdx, node.Value()) + err = s.checkInlineTable(parentIdx, value) + case ast.Array: + err = s.checkArray(parentIdx, value) } s.entries[parentIdx].kind = kind @@ -242,6 +247,32 @@ func (s *SeenTracker) checkKeyValue(parentIdx int, node *ast.Node) error { return err } +func (s *SeenTracker) checkArray(parentIdx int, node *ast.Node) error { + set := false + it := node.Children() + for it.Next() { + if set { + s.clear(parentIdx) + } + n := it.Node() + switch n.Kind { + case ast.InlineTable: + err := s.checkInlineTable(parentIdx, n) + if err != nil { + return err + } + set = true + case ast.Array: + err := s.checkArray(parentIdx, n) + if err != nil { + return err + } + set = true + } + } + return nil +} + func (s *SeenTracker) checkInlineTable(parentIdx int, node *ast.Node) error { it := node.Children() for it.Next() { diff --git a/unmarshaler_test.go b/unmarshaler_test.go index 26ea732..075fbeb 100644 --- a/unmarshaler_test.go +++ b/unmarshaler_test.go @@ -1916,6 +1916,12 @@ func TestIssue658(t *testing.T) { require.Error(t, err) } +func TestIssue662(t *testing.T) { + var v map[string]interface{} + err := toml.Unmarshal([]byte("a=[{b=1,b=2}]"), &v) + require.Error(t, err) +} + //nolint:funlen func TestUnmarshalDecodeErrors(t *testing.T) { examples := []struct {