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(), 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`