From f69be8c70561629e63004788f0aa4bf898025f93 Mon Sep 17 00:00:00 2001 From: Clara Engler Date: Wed, 3 Jun 2026 18:12:19 +0200 Subject: [PATCH 1/2] tor-netdoc: Avoid use of string slices in PortPolicy This commit removes the use of string slices in PortPolicy::from_str() by making use of `str::split_once` instead. See arti#2566 Co-authored-by: 5225225 <5225225@mailbox.org> --- crates/tor-netdoc/src/types/policy/portpolicy.rs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/crates/tor-netdoc/src/types/policy/portpolicy.rs b/crates/tor-netdoc/src/types/policy/portpolicy.rs index 7ca46aafa2..3f15cb6730 100644 --- a/crates/tor-netdoc/src/types/policy/portpolicy.rs +++ b/crates/tor-netdoc/src/types/policy/portpolicy.rs @@ -106,17 +106,11 @@ impl FromStr for PortPolicy { /// Very bad parser for [`PortPolicy`], please use `parse2`! fn from_str(s: &str) -> Result { // TODO: The error is bad but kept for backwards compatibility. - // Also, we should do split_whitespace but I feel doing this is not - // worth it anymore; introduces an unnecessary risk of adding - // bugs. - if s.len() < 7 { - // We need to do this because RuleKind::from_str does not check for - // the space between "accept/reject" and the arguments. - return Err(PolicyError::InvalidPort); - } - let kind = RuleKind::from_str(&s[..6]).map_err(|_| PolicyError::InvalidPort)?; - let s = &s[7..]; - let mut allowed = PortRanges::from_str(s)?; + // Splitting with a UTF-8 honoring method here is important, as + // RuleKind and PortRanges need their arguments separately. + let (kind, ranges) = s.split_once(' ').ok_or(PolicyError::InvalidPort)?; + let kind = RuleKind::from_str(kind).map_err(|_| PolicyError::InvalidPort)?; + let mut allowed = PortRanges::from_str(ranges)?; if kind == RuleKind::Reject { allowed.invert(); } -- GitLab From e715348e734f896e9aea4132fba1269db99a5467 Mon Sep 17 00:00:00 2001 From: 5225225 <5225225@mailbox.org> Date: Tue, 2 Jun 2026 15:47:00 +0100 Subject: [PATCH 2/2] tor-netdoc: Test for UTF-8 port policy edge case This commit adds a tor-netdoc test for checking for an edge case related to UTF-8 symbols found within netdocs. See arti#2566 --- crates/tor-netdoc/src/doc/microdesc.rs | 6 ++++++ crates/tor-netdoc/src/types/policy/portpolicy.rs | 1 + crates/tor-netdoc/testdata/bad-mds/non-ascii-policy | 10 ++++++++++ 3 files changed, 17 insertions(+) create mode 100644 crates/tor-netdoc/testdata/bad-mds/non-ascii-policy diff --git a/crates/tor-netdoc/src/doc/microdesc.rs b/crates/tor-netdoc/src/doc/microdesc.rs index 44892efc77..2b9c99e8a3 100644 --- a/crates/tor-netdoc/src/doc/microdesc.rs +++ b/crates/tor-netdoc/src/doc/microdesc.rs @@ -630,6 +630,12 @@ mod test { .at_pos(Pos::from_line(9, 1)) .with_source(PolicyError::InvalidPort), ); + check( + "non-ascii-policy", + &EK::BadPolicy + .at_pos(Pos::from_line(9, 1)) + .with_source(PolicyError::InvalidPort), + ); check("wrong-id", &EK::MissingToken.with_msg("id ed25519")); } diff --git a/crates/tor-netdoc/src/types/policy/portpolicy.rs b/crates/tor-netdoc/src/types/policy/portpolicy.rs index 3f15cb6730..4ba8db4ea6 100644 --- a/crates/tor-netdoc/src/types/policy/portpolicy.rs +++ b/crates/tor-netdoc/src/types/policy/portpolicy.rs @@ -250,6 +250,7 @@ mod test { "reject 1,1,1,1", "reject 1,2,foo,4", "reject 5,4,3,2", + "acce ¬", ] { assert!(s.parse::().is_err()); assert!( diff --git a/crates/tor-netdoc/testdata/bad-mds/non-ascii-policy b/crates/tor-netdoc/testdata/bad-mds/non-ascii-policy new file mode 100644 index 0000000000..dfd5765eb6 --- /dev/null +++ b/crates/tor-netdoc/testdata/bad-mds/non-ascii-policy @@ -0,0 +1,10 @@ +onion-key +-----BEGIN RSA PUBLIC KEY----- +MIGJAoGBALiyRXkiUmFQAmd1+Sy2ApNiPE4F54H7dKUwRqvCs+PqpqExaM2ybqMd +Zzjkgsp41jjOxk/m5RGyo+wLTo3C1TanWsf3CFfoL836KYiv9IjguIuH8FH/EpX1 +ss5ChhkkKNhPtvOMFfVe0iuN0abUdGSmixKUVNW0/LiNzXa9Fa/jAgMBAAE= +-----END RSA PUBLIC KEY----- +ntor-onion-key gkQqYIYcecF1KwS2wVV/oVQAuf6oeTWzswXFkEVs/nE= +family $0BC8BA32CC3CB0F598E0C92778F7C0946DFBCE91 $195712E96FD1C1B18D14D09E9E4E7A6416E23B2C $22404A3E87F2D7FE2FC6359FDE71B6DC2D6E730F $26C28F29B611DF4DE23ACF5D9DC1EB4895EF5E8B $486740353B905AA4731F82C0B4CC25821A62C6E3 $4D0DF468DC816F8096702C2DA2C6FD67561F81C8 $4DD902046E7155BBE79C34EE6D53BF7408B98CE4 $78BC2254D3B31CD865F7682633AA438212132532 $7B700C0C207EBD0002E00F499BE265519AC3C25A $846B3EAAF0C07FF72FC79AEBB11FA3ADC58F240F $868A253C330F40FBE435D9320849397F85823E86 $A60697FF383EEEE2E88505DD4E305C07BF326B11 $A690C6AA8102C027D297AF3401BFE16918CCF7A6 $A6AA94B4007A0E2919B2DA8ECF2CFA3CA1761A13 $C19B33758B3A5144894233EC4C95D7985B9FD101 $DC2191663DD4BAECB34F949CCAC3FDA004CE5BCE $F0F5074A6DADD3DC22E1FAA18FD6D89CBC52771A $FC077C25B8DBB3132D397D7DF03C92BFC14C9D76 +p6 acce ¬ +id ed25519 k3TwldYWObTQkjmY83o+uG6xcbD5b/Zda8QPc/C5Ftg -- GitLab