From 734bfdeaf290a64f4170f79770dfac7151951942 Mon Sep 17 00:00:00 2001 From: Smitty Date: Thu, 8 Jul 2021 14:13:42 -0400 Subject: [PATCH] Disallow octal zeros in IPv4 addresses --- library/std/src/net/ip/tests.rs | 8 ++++++++ library/std/src/net/parser.rs | 26 +++++++++++++++++--------- 2 files changed, 25 insertions(+), 9 deletions(-) diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index 2109980ad05..5ff0bd697b1 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -20,6 +20,14 @@ fn test_from_str_ipv4() { // no number between dots let none: Option = "255.0..1".parse().ok(); assert_eq!(None, none); + // octal + let none: Option = "255.0.0.01".parse().ok(); + assert_eq!(None, none); + // octal zero + let none: Option = "255.0.0.00".parse().ok(); + assert_eq!(None, none); + let none: Option = "255.0.00.0".parse().ok(); + assert_eq!(None, none); } #[test] diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 88a8cb76bef..d43d40400ab 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -12,7 +12,7 @@ use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6}; use crate::str::FromStr; -trait ReadNumberHelper: crate::marker::Sized { +trait ReadNumberHelper: crate::marker::Sized + crate::cmp::PartialEq { const ZERO: Self; fn checked_mul(&self, other: u32) -> Option; fn checked_add(&self, other: u32) -> Option; @@ -111,10 +111,12 @@ fn read_number( &mut self, radix: u32, max_digits: Option, + allow_zero_prefix: bool, ) -> Option { self.read_atomically(move |p| { let mut result = T::ZERO; let mut digit_count = 0; + let has_leading_zero = p.peek_char() == Some('0'); while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) { result = result.checked_mul(radix)?; @@ -127,7 +129,16 @@ fn read_number( } } - if digit_count == 0 { None } else { Some(result) } + if digit_count == 0 { + None + } else if !allow_zero_prefix + && has_leading_zero + && (result != T::ZERO || result == T::ZERO && digit_count > 1) + { + None + } else { + Some(result) + } }) } @@ -140,10 +151,7 @@ fn read_ipv4_addr(&mut self) -> Option { *slot = p.read_separator('.', i, |p| { // Disallow octal number in IP string. // https://tools.ietf.org/html/rfc6943#section-3.1.1 - match (p.peek_char(), p.read_number(10, None)) { - (Some('0'), Some(number)) if number != 0 => None, - (_, number) => number, - } + p.read_number(10, None, false) })?; } @@ -175,7 +183,7 @@ fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) { } } - let group = p.read_separator(':', i, |p| p.read_number(16, Some(4))); + let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true)); match group { Some(g) => *slot = g, @@ -227,7 +235,7 @@ fn read_ip_addr(&mut self) -> Option { fn read_port(&mut self) -> Option { self.read_atomically(|p| { p.read_given_char(':')?; - p.read_number(10, None) + p.read_number(10, None, true) }) } @@ -235,7 +243,7 @@ fn read_port(&mut self) -> Option { fn read_scope_id(&mut self) -> Option { self.read_atomically(|p| { p.read_given_char('%')?; - p.read_number(10, None) + p.read_number(10, None, true) }) } -- 2.44.0