From 2f9253c9eb6c968be8227284b873660bd3451007 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 2 Oct 2023 18:37:02 -0500 Subject: [PATCH 1/3] chore: Update toml-test --- Cargo.lock | 13 +++++++------ crates/toml/Cargo.toml | 3 ++- crates/toml_edit/Cargo.toml | 4 ++-- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1ea0930c..05a57737 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -893,6 +893,7 @@ dependencies = [ "serde_json", "serde_spanned", "snapbox", + "toml-test-data", "toml-test-harness", "toml_datetime", "toml_edit", @@ -900,9 +901,9 @@ dependencies = [ [[package]] name = "toml-test" -version = "0.3.4" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37351256790aa1dbd6d60f4ff08e55e7f372e292f3e9040d6e077463d9a779c3" +checksum = "a47dfa19ca3d6591b3151156884e0345e646307299a111391c54b0a7bd33bb04" dependencies = [ "chrono", "serde", @@ -911,18 +912,18 @@ dependencies = [ [[package]] name = "toml-test-data" -version = "1.3.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93f351b6d6005ee802b0d4a53ca1cdf05636f441df4d299e62cba57f1da52646" +checksum = "4340f0f6c69efad9058211393c1a2d959f48f01c291ae6b21ffdf14a7eeba503" dependencies = [ "include_dir", ] [[package]] name = "toml-test-harness" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e00fda5710922fe6b3005bf6a5050c303d6f9625249c37b7386e8818f4af675" +checksum = "2ab6273ee89f4204793309f471313bc53d5881c38f02dc33303904e77107d04e" dependencies = [ "ignore", "libtest-mimic", diff --git a/crates/toml/Cargo.toml b/crates/toml/Cargo.toml index 42dce811..e24e75e2 100644 --- a/crates/toml/Cargo.toml +++ b/crates/toml/Cargo.toml @@ -49,7 +49,8 @@ serde_spanned = { version = "0.6.3", path = "../serde_spanned", features = ["ser [dev-dependencies] serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" -toml-test-harness = "0.4.3" +toml-test-harness = "0.4.4" +toml-test-data = "1.3.1" snapbox = "0.4.11" [[test]] diff --git a/crates/toml_edit/Cargo.toml b/crates/toml_edit/Cargo.toml index 992a7f67..492d4e23 100644 --- a/crates/toml_edit/Cargo.toml +++ b/crates/toml_edit/Cargo.toml @@ -46,8 +46,8 @@ serde_spanned = { version = "0.6.3", path = "../serde_spanned", features = ["ser [dev-dependencies] serde_json = "1.0.96" -toml-test-harness = "0.4.3" -toml-test-data = "1.3.0" +toml-test-harness = "0.4.4" +toml-test-data = "1.3.1" libtest-mimic = "0.6.0" snapbox = { version = "0.4.11", features = ["harness"] } From e1f20378a2a8c78f182b2ac61f76eebd30990b77 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 2 Oct 2023 18:51:08 -0500 Subject: [PATCH 2/3] test: Verify with latest data --- Cargo.lock | 4 ++-- crates/toml/Cargo.toml | 2 +- crates/toml/tests/decoder_compliance.rs | 7 ++----- crates/toml/tests/encoder_compliance.rs | 1 + crates/toml_edit/Cargo.toml | 2 +- crates/toml_edit/tests/decoder_compliance.rs | 9 +++------ .../tests/fixtures/invalid/encoding/bad-codepoint.stderr | 1 + .../tests/fixtures/invalid/float/exp-trailing-us.stderr | 7 ++++--- .../tests/fixtures/invalid/float/inf-capital.stderr | 6 ++++++ .../tests/fixtures/invalid/float/nan-capital.stderr | 6 ++++++ .../fixtures/invalid/float/trailing-us-exp-1.stderr | 6 ++++++ .../fixtures/invalid/float/trailing-us-exp-2.stderr | 6 ++++++ .../tests/fixtures/invalid/float/trailing-us-exp.stderr | 6 ------ .../fixtures/invalid/inline-table/bad-key-syntax.stderr | 6 ++++++ .../invalid/inline-table/dotted-key-conflict.stderr | 5 +++++ .../invalid/inline-table/nested_key_conflict.stderr | 0 .../table/append-to-array-with-dotted-keys.stderr | 5 +++++ .../invalid/table/duplicate-key-dotted-array.stderr | 6 ++++++ 18 files changed, 61 insertions(+), 24 deletions(-) create mode 100644 crates/toml_edit/tests/fixtures/invalid/encoding/bad-codepoint.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/float/inf-capital.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/float/nan-capital.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-1.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-2.stderr delete mode 100644 crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/inline-table/dotted-key-conflict.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr create mode 100644 crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr diff --git a/Cargo.lock b/Cargo.lock index 05a57737..f82556f1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -921,9 +921,9 @@ dependencies = [ [[package]] name = "toml-test-harness" -version = "0.4.4" +version = "0.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab6273ee89f4204793309f471313bc53d5881c38f02dc33303904e77107d04e" +checksum = "7346ccc45965d33ad1a15e558bc67f8c7a35a72d882f646c342fea9227390296" dependencies = [ "ignore", "libtest-mimic", diff --git a/crates/toml/Cargo.toml b/crates/toml/Cargo.toml index e24e75e2..1568e4ee 100644 --- a/crates/toml/Cargo.toml +++ b/crates/toml/Cargo.toml @@ -49,7 +49,7 @@ serde_spanned = { version = "0.6.3", path = "../serde_spanned", features = ["ser [dev-dependencies] serde = { version = "1.0.160", features = ["derive"] } serde_json = "1.0.96" -toml-test-harness = "0.4.4" +toml-test-harness = "0.4.5" toml-test-data = "1.3.1" snapbox = "0.4.11" diff --git a/crates/toml/tests/decoder_compliance.rs b/crates/toml/tests/decoder_compliance.rs index 5d4fc2a4..280fe075 100644 --- a/crates/toml/tests/decoder_compliance.rs +++ b/crates/toml/tests/decoder_compliance.rs @@ -7,13 +7,10 @@ fn main() { harness .ignore([ "valid/spec/float-0.toml", - // Unreleased - "valid/string/escape-esc.toml", - "valid/string/hex-escape.toml", - "valid/datetime/no-seconds.toml", - "valid/inline-table/newline.toml", + "invalid/inline-table/nested_key_conflict.toml", ]) .unwrap(); + harness.version("1.0.0"); harness.test(); } diff --git a/crates/toml/tests/encoder_compliance.rs b/crates/toml/tests/encoder_compliance.rs index 38072483..8702b3af 100644 --- a/crates/toml/tests/encoder_compliance.rs +++ b/crates/toml/tests/encoder_compliance.rs @@ -7,6 +7,7 @@ fn main() { let decoder = decoder::Decoder; let mut harness = toml_test_harness::EncoderHarness::new(encoder, decoder); harness.ignore(["valid/spec/float-0.toml"]).unwrap(); + harness.version("1.0.0"); harness.test(); } diff --git a/crates/toml_edit/Cargo.toml b/crates/toml_edit/Cargo.toml index 492d4e23..03107fdd 100644 --- a/crates/toml_edit/Cargo.toml +++ b/crates/toml_edit/Cargo.toml @@ -46,7 +46,7 @@ serde_spanned = { version = "0.6.3", path = "../serde_spanned", features = ["ser [dev-dependencies] serde_json = "1.0.96" -toml-test-harness = "0.4.4" +toml-test-harness = "0.4.5" toml-test-data = "1.3.1" libtest-mimic = "0.6.0" snapbox = { version = "0.4.11", features = ["harness"] } diff --git a/crates/toml_edit/tests/decoder_compliance.rs b/crates/toml_edit/tests/decoder_compliance.rs index 0f0b3501..30861df1 100644 --- a/crates/toml_edit/tests/decoder_compliance.rs +++ b/crates/toml_edit/tests/decoder_compliance.rs @@ -5,13 +5,10 @@ fn main() { let mut harness = toml_test_harness::DecoderHarness::new(decoder); harness .ignore([ - "valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0` - // Unreleased - "valid/string/escape-esc.toml", - "valid/string/hex-escape.toml", - "valid/datetime/no-seconds.toml", - "valid/inline-table/newline.toml", + "valid/spec/float-0.toml", + "invalid/inline-table/nested_key_conflict.toml", ]) .unwrap(); + harness.version("1.0.0"); harness.test(); } diff --git a/crates/toml_edit/tests/fixtures/invalid/encoding/bad-codepoint.stderr b/crates/toml_edit/tests/fixtures/invalid/encoding/bad-codepoint.stderr new file mode 100644 index 00000000..89ef2c79 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/encoding/bad-codepoint.stderr @@ -0,0 +1 @@ +invalid utf-8 sequence of 1 bytes from index 29 \ No newline at end of file diff --git a/crates/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr b/crates/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr index 9a281849..b7e2ad9c 100644 --- a/crates/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr +++ b/crates/toml_edit/tests/fixtures/invalid/float/exp-trailing-us.stderr @@ -1,5 +1,6 @@ -TOML parse error at line 1, column 21 +TOML parse error at line 1, column 24 | -1 | exp-trailing-us = 1e_23_ - | ^ +1 | exp-trailing-us = 1e23_ + | ^ invalid floating-point number +expected digit diff --git a/crates/toml_edit/tests/fixtures/invalid/float/inf-capital.stderr b/crates/toml_edit/tests/fixtures/invalid/float/inf-capital.stderr new file mode 100644 index 00000000..ca7a1b1b --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/float/inf-capital.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | v = Inf + | ^ +invalid string +expected `"`, `'` diff --git a/crates/toml_edit/tests/fixtures/invalid/float/nan-capital.stderr b/crates/toml_edit/tests/fixtures/invalid/float/nan-capital.stderr new file mode 100644 index 00000000..ae3b4d95 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/float/nan-capital.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 5 + | +1 | v = NaN + | ^ +invalid string +expected `"`, `'` diff --git a/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-1.stderr b/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-1.stderr new file mode 100644 index 00000000..cf0fabc7 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-1.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 23 + | +1 | trailing-us-exp-1 = 1_e2 + | ^ +invalid integer +expected digit diff --git a/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-2.stderr b/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-2.stderr new file mode 100644 index 00000000..83ff1208 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp-2.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 25 + | +1 | trailing-us-exp-2 = 1.2_e2 + | ^ +invalid floating-point number +expected digit, digit diff --git a/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr b/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr deleted file mode 100644 index 811f951e..00000000 --- a/crates/toml_edit/tests/fixtures/invalid/float/trailing-us-exp.stderr +++ /dev/null @@ -1,6 +0,0 @@ -TOML parse error at line 2, column 21 - | -2 | trailing-us-exp = 1_e2 - | ^ -invalid integer -expected digit diff --git a/crates/toml_edit/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr b/crates/toml_edit/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr new file mode 100644 index 00000000..c8ce45a6 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 1, column 14 + | +1 | tbl = { a = 1, [b] } + | ^ +invalid inline table +expected `}` diff --git a/crates/toml_edit/tests/fixtures/invalid/inline-table/dotted-key-conflict.stderr b/crates/toml_edit/tests/fixtures/invalid/inline-table/dotted-key-conflict.stderr new file mode 100644 index 00000000..7b860448 --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/inline-table/dotted-key-conflict.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 8 + | +1 | tbl = { a.b = "a_b", a.b.c = "a_b_c" } + | ^ +dotted key `a.b` attempted to extend non-table type (string) diff --git a/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr b/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr new file mode 100644 index 00000000..e69de29b diff --git a/crates/toml_edit/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr b/crates/toml_edit/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr new file mode 100644 index 00000000..0fb4b2eb --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 4, column 1 + | +4 | b.y = 2 + | ^ +duplicate key `y` diff --git a/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr new file mode 100644 index 00000000..0cf32abe --- /dev/null +++ b/crates/toml_edit/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr @@ -0,0 +1,6 @@ +TOML parse error at line 4, column 1 + | +4 | [[fruit.apple]] + | ^ +invalid table header +duplicate key `apple` in table `fruit` From 7eaf2861106430833eb40e7b237fe5522be6bb03 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 2 Oct 2023 19:12:45 -0500 Subject: [PATCH 3/3] fix(parser): Failed on mixed inline tables --- crates/toml/tests/decoder_compliance.rs | 7 +---- crates/toml_edit/src/inline_table.rs | 28 +++++++++++++++++++ crates/toml_edit/src/parser/inline_table.rs | 23 ++++++++++++++- crates/toml_edit/tests/decoder_compliance.rs | 7 +---- .../inline-table/nested_key_conflict.stderr | 5 ++++ 5 files changed, 57 insertions(+), 13 deletions(-) diff --git a/crates/toml/tests/decoder_compliance.rs b/crates/toml/tests/decoder_compliance.rs index 280fe075..4e9e5b4c 100644 --- a/crates/toml/tests/decoder_compliance.rs +++ b/crates/toml/tests/decoder_compliance.rs @@ -4,12 +4,7 @@ mod decoder; fn main() { let decoder = decoder::Decoder; let mut harness = toml_test_harness::DecoderHarness::new(decoder); - harness - .ignore([ - "valid/spec/float-0.toml", - "invalid/inline-table/nested_key_conflict.toml", - ]) - .unwrap(); + harness.ignore(["valid/spec/float-0.toml"]).unwrap(); harness.version("1.0.0"); harness.test(); } diff --git a/crates/toml_edit/src/inline_table.rs b/crates/toml_edit/src/inline_table.rs index 3dc6c0c0..6009267e 100644 --- a/crates/toml_edit/src/inline_table.rs +++ b/crates/toml_edit/src/inline_table.rs @@ -11,6 +11,8 @@ use crate::{InternalString, Item, KeyMut, RawString, Table, Value}; pub struct InlineTable { // `preamble` represents whitespaces in an empty table preamble: RawString, + // Whether to hide an empty table + pub(crate) implicit: bool, // prefix before `{` and suffix after `}` decor: Decor, pub(crate) span: Option>, @@ -133,6 +135,32 @@ impl InlineTable { } } + /// If a table has no key/value pairs and implicit, it will not be displayed. + /// + /// # Examples + /// + /// ```notrust + /// [target."x86_64/windows.json".dependencies] + /// ``` + /// + /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit. + /// + /// ``` + /// use toml_edit::Document; + /// let mut doc = "[a]\n[a.b]\n".parse::().expect("invalid toml"); + /// + /// doc["a"].as_table_mut().unwrap().set_implicit(true); + /// assert_eq!(doc.to_string(), "[a.b]\n"); + /// ``` + pub(crate) fn set_implicit(&mut self, implicit: bool) { + self.implicit = implicit; + } + + /// If a table has no key/value pairs and implicit, it will not be displayed. + pub(crate) fn is_implicit(&self) -> bool { + self.implicit + } + /// Change this table's dotted status pub fn set_dotted(&mut self, yes: bool) { self.dotted = yes; diff --git a/crates/toml_edit/src/parser/inline_table.rs b/crates/toml_edit/src/parser/inline_table.rs index 994e0033..f7cf2e9c 100644 --- a/crates/toml_edit/src/parser/inline_table.rs +++ b/crates/toml_edit/src/parser/inline_table.rs @@ -44,6 +44,16 @@ fn table_from_pairs( for (path, kv) in v { let table = descend_path(&mut root, &path)?; + + // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed" + let mixed_table_types = table.is_dotted() == path.is_empty(); + if mixed_table_types { + return Err(CustomError::DuplicateKey { + key: kv.key.get().into(), + table: None, + }); + } + let key: InternalString = kv.key.get_internal().into(); match table.items.entry(key) { Entry::Vacant(o) => { @@ -64,15 +74,26 @@ fn descend_path<'a>( mut table: &'a mut InlineTable, path: &'a [Key], ) -> Result<&'a mut InlineTable, CustomError> { + let dotted = !path.is_empty(); for (i, key) in path.iter().enumerate() { let entry = table.entry_format(key).or_insert_with(|| { let mut new_table = InlineTable::new(); - new_table.set_dotted(true); + new_table.set_implicit(dotted); + new_table.set_dotted(dotted); Value::InlineTable(new_table) }); match *entry { Value::InlineTable(ref mut sweet_child_of_mine) => { + // 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 dotted && !sweet_child_of_mine.is_implicit() { + return Err(CustomError::DuplicateKey { + key: key.get().into(), + table: None, + }); + } table = sweet_child_of_mine; } ref v => { diff --git a/crates/toml_edit/tests/decoder_compliance.rs b/crates/toml_edit/tests/decoder_compliance.rs index 30861df1..cab69a48 100644 --- a/crates/toml_edit/tests/decoder_compliance.rs +++ b/crates/toml_edit/tests/decoder_compliance.rs @@ -3,12 +3,7 @@ mod decoder; fn main() { let decoder = decoder::Decoder; let mut harness = toml_test_harness::DecoderHarness::new(decoder); - harness - .ignore([ - "valid/spec/float-0.toml", - "invalid/inline-table/nested_key_conflict.toml", - ]) - .unwrap(); + harness.ignore(["valid/spec/float-0.toml"]).unwrap(); harness.version("1.0.0"); harness.test(); } diff --git a/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr b/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr index e69de29b..79a80410 100644 --- a/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr +++ b/crates/toml_edit/tests/fixtures/invalid/inline-table/nested_key_conflict.stderr @@ -0,0 +1,5 @@ +TOML parse error at line 1, column 8 + | +1 | tbl = { fruit = { apple.color = "red" }, fruit.apple.texture = { smooth = true } } + | ^ +duplicate key `fruit`