Repository: toml-rs/toml
Pull request #418 (2023-01-03 04:47:40)

fix(parser): Catch more dotted key interactions


Patch:
diff --git a/crates/toml_edit/src/parser/state.rs b/crates/toml_edit/src/parser/state.rs
index 2a286456..6733753d 100644
--- a/crates/toml_edit/src/parser/state.rs
+++ b/crates/toml_edit/src/parser/state.rs
@@ -116,9 +116,10 @@ impl ParseState {
         let key = &path[path.len() - 1];
         if let Some(entry) = parent_table.remove(key.get()) {
             match entry {
-                Item::Table(t) if t.implicit => {
+                Item::Table(t) if t.implicit && !t.is_dotted() => {
                     self.current_table = t;
                 }
+                // Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed. Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed.
                 _ => return Err(CustomError::duplicate_key(&path, path.len() - 1)),
             }
         }
@@ -202,7 +203,15 @@ impl ParseState {
                     table = last_child;
                 }
                 Item::Table(ref mut sweet_child_of_mine) => {
-                    // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed"
+                    // Since tables cannot be defined more than once, redefining such tables using a
+                    // [table] header is not allowed. Likewise, using dotted keys to redefine tables
+                    // already defined in [table] form is not allowed.
+                    if sweet_child_of_mine.is_dotted() && !dotted {
+                        return Err(CustomError::DuplicateKey {
+                            key: key.get().into(),
+                            table: None,
+                        });
+                    }
                     if dotted && !sweet_child_of_mine.is_implicit() {
                         return Err(CustomError::DuplicateKey {
                             key: key.get().into(),


Test patch:
diff --git a/crates/toml_edit/tests/decoder_compliance.rs b/crates/toml_edit/tests/decoder_compliance.rs
index 0bb1ef3e..b23fdca2 100644
--- a/crates/toml_edit/tests/decoder_compliance.rs
+++ b/crates/toml_edit/tests/decoder_compliance.rs
@@ -3,12 +3,6 @@ mod decoder;
 fn main() {
     let decoder = decoder::Decoder;
     let mut harness = toml_test_harness::DecoderHarness::new(decoder);
-    harness
-        .ignore([
-            "valid/string/escape-esc.toml",
-            "invalid/table/duplicate-key-dotted-table.toml",
-            "invalid/table/duplicate-key-dotted-table2.toml",
-        ])
-        .unwrap();
+    harness.ignore(["valid/string/escape-esc.toml"]).unwrap();
     harness.test();
 }
diff --git a/crates/toml_edit/tests/easy_decoder_compliance.rs b/crates/toml_edit/tests/easy_decoder_compliance.rs
index 71075732..5deb2d41 100644
--- a/crates/toml_edit/tests/easy_decoder_compliance.rs
+++ b/crates/toml_edit/tests/easy_decoder_compliance.rs
@@ -5,13 +5,7 @@ mod easy_decoder;
 fn main() {
     let decoder = easy_decoder::Decoder;
     let mut harness = toml_test_harness::DecoderHarness::new(decoder);
-    harness
-        .ignore([
-            "valid/string/escape-esc.toml",
-            "invalid/table/duplicate-key-dotted-table.toml",
-            "invalid/table/duplicate-key-dotted-table2.toml",
-        ])
-        .unwrap();
+    harness.ignore(["valid/string/escape-esc.toml"]).unwrap();
     harness.test();
 }
 
diff --git a/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr
index e69de29b..20480878 100644
--- a/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr
+++ b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 4, column 1
+  |
+4 | [fruit.apple] # INVALID
+  | ^
+Invalid table header
+Duplicate key `apple` in table `fruit`
diff --git a/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr
index e69de29b..f7346cd8 100644
--- a/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr
+++ b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-table2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 4, column 1
+  |
+4 | [fruit.apple.taste] # INVALID
+  | ^
+Invalid table header
+Duplicate key `apple`