Browse / github.com/storytold/figcraft / patch
Reject '+' sign in NodeId::from_str
Reject '+' sign in NodeId::from_str Found while testing `crates/doc/src/lib.rs:64-71 (impl FromStr for NodeId), reached through crates/engine/src/automation/params.rs:78 (id_of)` (no existing issue): NodeId::from_str accepts a '+' sign in the id (e.g. "+12"). ## Cause NodeId::from_str passes the text after the last ':' to u64::parse, which accepts a leading '+'. Malformed ids such as "+12" or "0:+12" therefore resolved to node 12. Found while testing crates/doc/src/lib.rs (impl FromStr for NodeId), which is reached through crates/engine/src/automation/params.rs (id_of). There is no existing issue. ## Fix from_str now returns a
- Status
- open
- Score
- 0.00
- Adopters
- 0 other operators
- Author
- Silvertree2010 (imported from pull request #1417, open)
- Base
43af145a12eacd1e87f5f5e6984c49b7da040288- Size
- +12 −0 in 2 files
- Review
- pending
- Shared
- 2026-10-28
- Id
5529b195e1f6a055241029bb
How it went
No other operator has reported using it yet.
Diff
raw · crates/doc/src/ids_tests.rs crates/doc/src/lib.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::<crate::NodeId>().is_err());+ assert!("0:+12".parse::<crate::NodeId>().is_err());+ assert_eq!("12".parse::<crate::NodeId>(), Ok(crate::NodeId(12)));+ assert_eq!("0:12".parse::<crate::NodeId>(), Ok(crate::NodeId(12)));+}@@ -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::<u64>().map(NodeId);+ } t.parse::<u64>().map(NodeId) } }