Skip to content

Commit

Permalink
seen: check inline tables
Browse files Browse the repository at this point in the history
Fixes #658
  • Loading branch information
pelletier committed Nov 9, 2021
1 parent dc1740d commit 53f3db4
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 9 deletions.
33 changes: 24 additions & 9 deletions internal/tracker/seen.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ type entry struct {
explicit bool
}

// Remove all descendent of node at position idx.
// Remove all descendants of node at position idx.
func (s *SeenTracker) clear(idx int) {
p := s.entries[idx].id
rest := clear(p, s.entries[idx+1:])
Expand Down Expand Up @@ -102,19 +102,21 @@ func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit
return idx
}

// CheckExpression takes a top-level node and checks that it does not contain keys
// that have been seen in previous calls, and validates that types are consistent.
// CheckExpression takes a top-level node and checks that it does not contain
// keys that have been seen in previous calls, and validates that types are
// consistent.
func (s *SeenTracker) CheckExpression(node *ast.Node) error {
if s.entries == nil {
// Skip ID = 0 to remove the confusion between nodes whose parent has
// id 0 and root nodes (parent id is 0 because it's the zero value).
// Skip ID = 0 to remove the confusion between nodes whose
// parent has id 0 and root nodes (parent id is 0 because it's
// the zero value).
s.nextID = 1
// Start unscoped, so idx is negative.
s.currentIdx = -1
}
switch node.Kind {
case ast.KeyValue:
return s.checkKeyValue(node)
return s.checkKeyValue(s.currentIdx, node)
case ast.Table:
return s.checkTable(node)
case ast.ArrayTable:
Expand Down Expand Up @@ -206,11 +208,9 @@ func (s *SeenTracker) checkArrayTable(node *ast.Node) error {
return nil
}

func (s *SeenTracker) checkKeyValue(node *ast.Node) error {
func (s *SeenTracker) checkKeyValue(parentIdx int, node *ast.Node) error {
it := node.Key()

parentIdx := s.currentIdx

for it.Next() {
k := it.Node().Data

Expand All @@ -230,12 +230,27 @@ func (s *SeenTracker) checkKeyValue(node *ast.Node) error {
}

kind := valueKind
var err error

if node.Value().Kind == ast.InlineTable {
kind = tableKind
err = s.checkInlineTable(parentIdx, node.Value())
}

s.entries[parentIdx].kind = kind

return err
}

func (s *SeenTracker) checkInlineTable(parentIdx int, node *ast.Node) error {
it := node.Children()
for it.Next() {
n := it.Node()
err := s.checkKeyValue(parentIdx, n)
if err != nil {
return err
}
}
return nil
}

Expand Down
6 changes: 6 additions & 0 deletions unmarshaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,12 @@ func TestIssue564(t *testing.T) {
require.Equal(t, uuid{0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA}, config.ID)
}

func TestIssue658(t *testing.T) {
var v map[string]interface{}
err := toml.Unmarshal([]byte("e={b=1,b=4}"), &v)
require.Error(t, err)
}

//nolint:funlen
func TestUnmarshalDecodeErrors(t *testing.T) {
examples := []struct {
Expand Down

0 comments on commit 53f3db4

Please sign in to comment.