From 9b02d8b49ce7070362e6eb1f051af560c42e4cad Mon Sep 17 00:00:00 2001 From: Nicholas Connor Date: Tue, 17 May 2022 12:11:24 -0400 Subject: [PATCH 1/3] add optimized parsing rule for known bad ipv4 --- library/std/src/net/parser.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index 069b660998559..cc3bed535ad92 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -285,8 +285,8 @@ impl FromStr for IpAddr { impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - // don't try to parse if too long - if s.len() > 15 { + // don't try to parse if too long or too short + if s.len() < 7 || s.len() > 15 { Err(AddrParseError(AddrKind::Ipv4)) } else { Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) From 4783dc5ba18a71179cf4a01dcd080e3346277745 Mon Sep 17 00:00:00 2001 From: nkconnor Date: Tue, 9 Aug 2022 14:58:48 -0400 Subject: [PATCH 2/3] apply ipv4 parser length checks to more situations --- library/std/src/net/parser.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index cc3bed535ad92..b1c684d5fc53e 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -140,6 +140,11 @@ impl<'a> Parser<'a> { /// Read an IPv4 address. fn read_ipv4_addr(&mut self) -> Option { + // don't try to parse if too short or long + if self.state.len() < 7 || self.state.len() > 15 { + return None; + } + self.read_atomically(|p| { let mut groups = [0; 4]; @@ -285,12 +290,7 @@ impl FromStr for IpAddr { impl FromStr for Ipv4Addr { type Err = AddrParseError; fn from_str(s: &str) -> Result { - // don't try to parse if too long or too short - if s.len() < 7 || s.len() > 15 { - Err(AddrParseError(AddrKind::Ipv4)) - } else { - Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) - } + Parser::new(s).parse_with(|p| p.read_ipv4_addr(), AddrKind::Ipv4) } } From 2aab9afd01ed71b6df3024c7f6a2c6d2343a4739 Mon Sep 17 00:00:00 2001 From: nkconnor Date: Tue, 9 Aug 2022 16:11:41 -0400 Subject: [PATCH 3/3] fix parser length checks to depend on the type of addr being parsed --- library/std/src/net/parser.rs | 32 +++++++++++++++++++++++++++----- 1 file changed, 27 insertions(+), 5 deletions(-) diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs index b1c684d5fc53e..5c5ff90fa518c 100644 --- a/library/std/src/net/parser.rs +++ b/library/std/src/net/parser.rs @@ -62,6 +62,13 @@ impl<'a> Parser<'a> { where F: FnOnce(&mut Parser<'_>) -> Option, { + // don't try to parse if too short or too long + if self.state.len() > kind.max_string_length() + || self.state.len() < kind.min_string_length() + { + return Err(AddrParseError(kind)); + } + let result = inner(self); if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(kind)) } @@ -140,11 +147,6 @@ impl<'a> Parser<'a> { /// Read an IPv4 address. fn read_ipv4_addr(&mut self) -> Option { - // don't try to parse if too short or long - if self.state.len() < 7 || self.state.len() > 15 { - return None; - } - self.read_atomically(|p| { let mut groups = [0; 4]; @@ -336,6 +338,26 @@ enum AddrKind { SocketV6, } +impl AddrKind { + // the minimum length of a parsable string with this `AddrKind` + const fn min_string_length(&self) -> usize { + match self { + Self::Ip | Self::Ipv4 => 7, + // FIXME + _ => 0, + } + } + + // the maximum length of a parsable string with this `AddrKind` + const fn max_string_length(&self) -> usize { + match self { + Self::Ipv4 => 15, + // FIXME + _ => usize::MAX, + } + } +} + /// An error which can be returned when parsing an IP address or a socket address. /// /// This error is used as the error type for the [`FromStr`] implementation for