diff --git a/crates/doc/src/ids_tests.rs b/crates/doc/src/ids_tests.rs index 4f489886..350d198c 100644 --- a/crates/doc/src/ids_tests.rs +++ b/crates/doc/src/ids_tests.rs @@ -110,3 +110,11 @@ fn the_highest_space_counts_every_kind_of_id() { assert_eq!(id_space("S:99999999999999999999999", "S:"), 0, "too big for a number"); assert_eq!(mode_number("1:0"), None); } + +#[test] +fn nodeid_rejects_plus_sign() { + assert!("+12".parse::().is_err()); + assert!("0:+12".parse::().is_err()); + assert_eq!("12".parse::(), Ok(crate::NodeId(12))); + assert_eq!("0:12".parse::(), Ok(crate::NodeId(12))); +} diff --git a/crates/doc/src/lib.rs b/crates/doc/src/lib.rs index caf0c861..8307296d 100644 --- a/crates/doc/src/lib.rs +++ b/crates/doc/src/lib.rs @@ -67,6 +67,10 @@ impl std::str::FromStr for NodeId { // Accept "12" and Figma-style "0:12". let t = s.trim(); let t = t.rsplit(':').next().unwrap_or(t); + if t.starts_with('+') { + // `u64::parse` accepts a leading '+'; ids are digits only. + return "-".parse::().map(NodeId); + } t.parse::().map(NodeId) } }