From f9903789d1134f5c484fdab3d4f3d4a710e3d76e Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Wed, 25 Jan 2023 16:29:53 -0500 Subject: [PATCH] Upgrade toml to version 0.6. This required rewriting some of our error handling code in command-line processing, since the toml crate now displays and reports errors differently. (Admittedly, this code still is kind of ugly, but at least it is nicely hidden.) --- Cargo.lock | 96 ++++++++++++++++++++++++-------- crates/arti/Cargo.toml | 2 +- crates/fs-mistrust/Cargo.toml | 2 +- crates/tor-config/Cargo.toml | 2 +- crates/tor-config/src/cmdline.rs | 66 +++++++++++++--------- crates/tor-guardmgr/Cargo.toml | 2 +- 6 files changed, 118 insertions(+), 52 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index aab044a91..1a2973682 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -116,7 +116,7 @@ dependencies = [ "signal-hook", "signal-hook-async-std", "tokio", - "toml", + "toml 0.6.0", "tor-config", "tor-error", "tor-rtcompat", @@ -735,7 +735,7 @@ dependencies = [ "nom", "pathdiff", "serde", - "toml", + "toml 0.5.11", ] [[package]] @@ -1302,7 +1302,7 @@ dependencies = [ "serde_json", "tempfile", "thiserror", - "toml", + "toml 0.6.0", "users", "walkdir", ] @@ -2050,6 +2050,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "nom8" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" +dependencies = [ + "memchr", +] + [[package]] name = "notify" version = "5.0.0" @@ -2197,9 +2206,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.16.0" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86f0b0d4bf799edbc74508c1e8bf170ff5f41238e5f8225603ca7caaae2b7860" +checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" [[package]] name = "opaque-debug" @@ -2486,14 +2495,14 @@ checksum = "eda0fc3b0fb7c975631757e14d9049da17374063edb6ebbcbc54d880d4fe94e9" dependencies = [ "once_cell", "thiserror", - "toml", + "toml 0.5.11", ] [[package]] name = "proc-macro2" -version = "1.0.47" +version = "1.0.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ea3d908b0e36316caf9e9e2c4625cdde190a7e6f440d794667ed17a1855e725" +checksum = "6ef7d57beacfaf2d8aee5937dab7b7f28de3cb8b1828479bb5de2a7106f2bae2" dependencies = [ "unicode-ident", ] @@ -2506,9 +2515,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.21" +version = "1.0.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbe448f377a7d6961e30f5955f9b8d106c3f5e449d493ee1b125c1d43c2b5179" +checksum = "8856d8364d252a14d474036ea1358d63c9e6965c8e5c1885c18f73d70bff9c7b" dependencies = [ "proc-macro2", ] @@ -2905,18 +2914,18 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4" [[package]] name = "serde" -version = "1.0.148" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc" +checksum = "bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.148" +version = "1.0.152" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c" +checksum = "af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e" dependencies = [ "proc-macro2", "quote", @@ -2943,6 +2952,15 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_spanned" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c68e921cef53841b8925c2abadd27c9b891d9613bdc43d6b823062866df38e8" +dependencies = [ + "serde", +] + [[package]] name = "serde_test" version = "1.0.148" @@ -3252,9 +3270,9 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "syn" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908" +checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" dependencies = [ "proc-macro2", "quote", @@ -3514,13 +3532,47 @@ dependencies = [ [[package]] name = "toml" -version = "0.5.9" +version = "0.5.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d82e1a7758622a465f8cee077614c73484dac5b836c02ff6a40d5d1010324d7" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" dependencies = [ "serde", ] +[[package]] +name = "toml" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb9d890e4dc9298b70f740f615f2e05b9db37dce531f6b24fb77ac993f9f217" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "729bfd096e40da9c001f778f5cdecbd2957929a24e10e5883d9392220a751581" +dependencies = [ + "indexmap", + "nom8", + "serde", + "serde_spanned", + "toml_datetime", +] + [[package]] name = "tor-basic-utils" version = "0.5.0" @@ -3709,7 +3761,7 @@ dependencies = [ "strum", "tempfile", "thiserror", - "toml", + "toml 0.6.0", "tor-basic-utils", "tor-error", "tracing", @@ -3868,7 +3920,7 @@ dependencies = [ "serde_json", "strum", "thiserror", - "toml", + "toml 0.6.0", "tor-basic-utils", "tor-config", "tor-error", @@ -4364,9 +4416,9 @@ checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" [[package]] name = "unicode-ident" -version = "1.0.5" +version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6ceab39d59e4c9499d4e5a8ee0e2735b891bb7308ac83dfb4e80cad195c9f6f3" +checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" [[package]] name = "unicode-normalization" diff --git a/crates/arti/Cargo.toml b/crates/arti/Cargo.toml index 93f7cb4b5..ebd27e2fe 100644 --- a/crates/arti/Cargo.toml +++ b/crates/arti/Cargo.toml @@ -104,7 +104,7 @@ visibility = { version = "0.0.1", optional = true } itertools = "0.10.1" regex = { version = "1", default-features = false, features = ["std"] } serde_json = "1.0.50" -toml = "0.5.6" +toml = "0.6.0" [target.'cfg(windows)'.dependencies] winapi = { version = "0.3.8", features = ["winerror"] } diff --git a/crates/fs-mistrust/Cargo.toml b/crates/fs-mistrust/Cargo.toml index 57369c63a..93cf5ae24 100644 --- a/crates/fs-mistrust/Cargo.toml +++ b/crates/fs-mistrust/Cargo.toml @@ -35,7 +35,7 @@ users = "0.11" [dev-dependencies] serde_json = "1.0.50" tempfile = "3" -toml = "0.5.6" +toml = "0.6.0" [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] diff --git a/crates/tor-config/Cargo.toml b/crates/tor-config/Cargo.toml index 66804bcef..256859dbb 100644 --- a/crates/tor-config/Cargo.toml +++ b/crates/tor-config/Cargo.toml @@ -31,7 +31,7 @@ serde_ignored = "0.1.3" shellexpand = { version = "3.0", optional = true } strum = { version = "0.24", features = ["derive"] } thiserror = "1" -toml = "0.5.6" +toml = "0.6.0" tor-basic-utils = { path = "../tor-basic-utils", version = "0.5.0" } tor-error = { path = "../tor-error", version = "0.4.0" } tracing = "0.1.18" diff --git a/crates/tor-config/src/cmdline.rs b/crates/tor-config/src/cmdline.rs index 00f1dd8f5..c28ac3fbb 100644 --- a/crates/tor-config/src/cmdline.rs +++ b/crates/tor-config/src/cmdline.rs @@ -45,25 +45,36 @@ impl CmdLine { } /// Try to adjust the contents of a toml deserialization error so /// that instead it refers to a single command-line argument. - fn convert_toml_error(&self, s: &str, pos: Option<(usize, usize)>) -> String { - /// Regex to match an error message from the toml crate. - static RE: Lazy = Lazy::new(|| { - Regex::new(r"^(.*?) at line [0-9]+ column [0-9]+$").expect("Can't compile regex") - }); - let cap = RE.captures(s); - let msg = match cap { - Some(c) => c.get(1).expect("mismatch regex: no capture group").as_str(), - None => s, - }; + fn convert_toml_error( + &self, + toml_str: &str, + error_message: &str, + span: &Option>, + ) -> String { + // Function to translate a string index to a 0-offset line number. + let linepos = |idx| toml_str.bytes().take(idx).filter(|b| *b == b'\n').count(); - let location = match pos { - Some((line, _col)) if line < self.contents.len() => { - format!(" in {:?}", self.contents[line]) + // Find the source position as a line within toml_str, and convert that + // to an index into self.contents. + let source_line = span + .as_ref() + .and_then(|range| { + let startline = linepos(range.start); + let endline = linepos(range.end); + (startline == endline).then(|| startline) + }) + .and_then(|pos| self.contents.get(pos)); + + match (source_line, span.as_ref()) { + (Some(source), _) => { + format!("Couldn't parse command line: {error_message} in {source:?}") } - _ => " on command line".to_string(), - }; - - format!("{}{}", msg, location) + (None, Some(range)) if toml_str.get(range.clone()).is_some() => format!( + "Couldn't parse command line: {error_message} within {:?}", + &toml_str[range.clone()] + ), + _ => format!("Couldn't parse command line: {error_message}"), + } } /// Compose elements of this cmdline into a single toml string. @@ -86,9 +97,11 @@ impl Source for CmdLine { let toml_s = self.build_toml(); let toml_v: toml::Value = match toml::from_str(&toml_s) { Err(e) => { - return Err(ConfigError::Message( - self.convert_toml_error(&e.to_string(), e.line_col()), - )) + return Err(ConfigError::Message(self.convert_toml_error( + &toml_s, + e.message(), + &e.span(), + ))) } Ok(v) => v, }; @@ -161,20 +174,21 @@ mod test { cl.push_toml_line("Hello=world".to_string()); cl.push_toml_line("Hola=mundo".to_string()); cl.push_toml_line("Bonjour=monde".to_string()); + let toml_s = cl.build_toml(); assert_eq!( - &cl.convert_toml_error("Nice greeting at line 1 column 1", Some((0, 1))), - "Nice greeting in \"Hello=world\"" + &cl.convert_toml_error(&toml_s, "Nice greeting", &Some(0..13)), + "Couldn't parse command line: Nice greeting in \"Hello=world\"" ); assert_eq!( - &cl.convert_toml_error("Nice greeting at line 1 column 1", Some((7, 1))), - "Nice greeting on command line" + &cl.convert_toml_error(&toml_s, "Nice greeting", &Some(99..333)), + "Couldn't parse command line: Nice greeting" ); assert_eq!( - &cl.convert_toml_error("Nice greeting with a thing", Some((0, 1))), - "Nice greeting with a thing in \"Hello=world\"" + &cl.convert_toml_error(&toml_s, "Nice greeting with a thing", &Some(0..13)), + "Couldn't parse command line: Nice greeting with a thing in \"Hello=world\"" ); } diff --git a/crates/tor-guardmgr/Cargo.toml b/crates/tor-guardmgr/Cargo.toml index 33395638c..64e08fe24 100644 --- a/crates/tor-guardmgr/Cargo.toml +++ b/crates/tor-guardmgr/Cargo.toml @@ -63,7 +63,7 @@ tracing = "0.1.18" [dev-dependencies] float_eq = "1.0.0" serde_json = "1.0.50" -toml = "0.5.6" +toml = "0.6.0" tor-netdir = { path = "../tor-netdir", version = "0.7.0", features = ["testing"] } tor-netdoc = { path = "../tor-netdoc", version = "0.6.0" } tor-persist = { path = "../tor-persist", version = "0.6.0", features = ["testing"] }