diff --git a/internal/tracker/seen.go b/internal/tracker/seen.go index af70241..8990dae 100644 --- a/internal/tracker/seen.go +++ b/internal/tracker/seen.go @@ -106,7 +106,6 @@ func (s *SeenTracker) create(parentIdx int, name []byte, kind keyKind, explicit // 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 { - // s.entries = make([]entry, 0, 8) // 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 @@ -221,6 +220,9 @@ func (s *SeenTracker) checkKeyValue(node *ast.Node) error { if s.entries[idx].kind != tableKind { return fmt.Errorf("toml: expected %s to be a table, not a %s", string(k), s.entries[idx].kind) } + if s.entries[idx].explicit { + return fmt.Errorf("toml: cannot redefine table %s that has already been explicitly defined", string(k)) + } } else { idx = s.create(parentIdx, k, tableKind, false) } diff --git a/toml_testgen_test.go b/toml_testgen_test.go index 3f3bcf5..61985ff 100644 --- a/toml_testgen_test.go +++ b/toml_testgen_test.go @@ -886,13 +886,11 @@ func TestTOMLTest_Invalid_Table_EqualsSign(t *testing.T) { } func TestTOMLTest_Invalid_Table_Injection1(t *testing.T) { - t.Skip("FIXME") input := "[a.b.c]\n z = 9\n[a]\n b.c.t = \"Using dotted keys to add to [a.b.c] after explicitly defining it above is not allowed\"\n \n# see https://github.com/toml-lang/toml/issues/846\n" testgenInvalid(t, input) } func TestTOMLTest_Invalid_Table_Injection2(t *testing.T) { - t.Skip("FIXME") input := "[a.b.c.d]\n z = 9\n[a]\n b.c.d.k.t = \"Using dotted keys to add to [a.b.c.d] after explicitly defining it above is not allowed\"\n \n# see https://github.com/toml-lang/toml/issues/846\n" testgenInvalid(t, input) } diff --git a/unmarshaler.go b/unmarshaler.go index dbe7cb0..19efaa4 100644 --- a/unmarshaler.go +++ b/unmarshaler.go @@ -516,6 +516,11 @@ func (d *decoder) handleKeyValues(v reflect.Value) (reflect.Value, error) { break } + err := d.seen.CheckExpression(expr) + if err != nil { + return reflect.Value{}, err + } + x, err := d.handleKeyValue(expr, v) if err != nil { return reflect.Value{}, err