about summary refs log tree commit diff
path: root/library/std/src/net/parser.rs
diff options
context:
space:
mode:
authorCheng XU <git@xuc.me>2021-03-30 10:24:23 +0800
committerCheng XU <git@xuc.me>2021-03-30 10:24:23 +0800
commit974192cd98b3efca8e5cd293f641f561e7487b30 (patch)
tree24dcd22450f5d66a050914c2e3f37a2021efcc99 /library/std/src/net/parser.rs
parent3aedcf06b73fc36feeebca3d579e1d2a6c40acc5 (diff)
downloadrust-974192cd98b3efca8e5cd293f641f561e7487b30.tar.gz
rust-974192cd98b3efca8e5cd293f641f561e7487b30.zip
Disallow octal format in Ipv4 string
In its original specification, leading zero in Ipv4 string is interpreted
as octal literals. So a IP address 0127.0.0.1 actually means 87.0.0.1.

This confusion can lead to many security vulnerabilities. Therefore, in
[IETF RFC 6943], it suggests to disallow octal/hexadecimal format in Ipv4
string all together.

Existing implementation already disallows hexadecimal numbers. This commit
makes Parser reject octal numbers.

Fixes #83648.

[IETF RFC 6943]: https://tools.ietf.org/html/rfc6943#section-3.1.1
Diffstat (limited to 'library/std/src/net/parser.rs')
-rw-r--r--library/std/src/net/parser.rs14
1 files changed, 13 insertions, 1 deletions
diff --git a/library/std/src/net/parser.rs b/library/std/src/net/parser.rs
index 7064ed3ed23..88a8cb76bef 100644
--- a/library/std/src/net/parser.rs
+++ b/library/std/src/net/parser.rs
@@ -67,6 +67,11 @@ impl<'a> Parser<'a> {
         if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(()))
     }
 
+    /// Peek the next character from the input
+    fn peek_char(&self) -> Option<char> {
+        self.state.first().map(|&b| char::from(b))
+    }
+
     /// Read the next character from the input
     fn read_char(&mut self) -> Option<char> {
         self.state.split_first().map(|(&b, tail)| {
@@ -132,7 +137,14 @@ impl<'a> Parser<'a> {
             let mut groups = [0; 4];
 
             for (i, slot) in groups.iter_mut().enumerate() {
-                *slot = p.read_separator('.', i, |p| p.read_number(10, None))?;
+                *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,
+                    }
+                })?;
             }
 
             Some(groups.into())