1//! A private parser implementation of IPv4, IPv6, and socket addresses.
2//!
3//! This module is "publicly exported" through the `FromStr` implementations
4//! below.
5
6use crate::convert::TryInto;
7use crate::error::Error;
8use crate::fmt;
9use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
10use crate::str::FromStr;
11
12trait ReadNumberHelper: Sized {
13 const ZERO: Self;
14 fn checked_mul(&self, other: u32) -> Option<Self>;
15 fn checked_add(&self, other: u32) -> Option<Self>;
16}
17
18macro_rules! impl_helper {
19 ($($t:ty)*) => ($(impl ReadNumberHelper for $t {
20 const ZERO: Self = 0;
21 #[inline]
22 fn checked_mul(&self, other: u32) -> Option<Self> {
23 Self::checked_mul(*self, other.try_into().ok()?)
24 }
25 #[inline]
26 fn checked_add(&self, other: u32) -> Option<Self> {
27 Self::checked_add(*self, other.try_into().ok()?)
28 }
29 })*)
30}
31
32impl_helper! { u8 u16 u32 }
33
34struct Parser<'a> {
35 // Parsing as ASCII, so can use byte array.
36 state: &'a [u8],
37}
38
39impl<'a> Parser<'a> {
40 fn new(input: &'a [u8]) -> Parser<'a> {
41 Parser { state: input }
42 }
43
44 /// Run a parser, and restore the pre-parse state if it fails.
45 fn read_atomically<T, F>(&mut self, inner: F) -> Option<T>
46 where
47 F: FnOnce(&mut Parser<'_>) -> Option<T>,
48 {
49 let state = self.state;
50 let result = inner(self);
51 if result.is_none() {
52 self.state = state;
53 }
54 result
55 }
56
57 /// Run a parser, but fail if the entire input wasn't consumed.
58 /// Doesn't run atomically.
59 fn parse_with<T, F>(&mut self, inner: F, kind: AddrKind) -> Result<T, AddrParseError>
60 where
61 F: FnOnce(&mut Parser<'_>) -> Option<T>,
62 {
63 let result = inner(self);
64 if self.state.is_empty() { result } else { None }.ok_or(AddrParseError(kind))
65 }
66
67 /// Peek the next character from the input
68 fn peek_char(&self) -> Option<char> {
69 self.state.first().map(|&b| char::from(b))
70 }
71
72 /// Read the next character from the input
73 fn read_char(&mut self) -> Option<char> {
74 self.state.split_first().map(|(&b, tail)| {
75 self.state = tail;
76 char::from(b)
77 })
78 }
79
80 #[must_use]
81 /// Read the next character from the input if it matches the target.
82 fn read_given_char(&mut self, target: char) -> Option<()> {
83 self.read_atomically(|p| {
84 p.read_char().and_then(|c| if c == target { Some(()) } else { None })
85 })
86 }
87
88 /// Helper for reading separators in an indexed loop. Reads the separator
89 /// character iff index > 0, then runs the parser. When used in a loop,
90 /// the separator character will only be read on index > 0 (see
91 /// read_ipv4_addr for an example)
92 fn read_separator<T, F>(&mut self, sep: char, index: usize, inner: F) -> Option<T>
93 where
94 F: FnOnce(&mut Parser<'_>) -> Option<T>,
95 {
96 self.read_atomically(move |p| {
97 if index > 0 {
98 p.read_given_char(sep)?;
99 }
100 inner(p)
101 })
102 }
103
104 // Read a number off the front of the input in the given radix, stopping
105 // at the first non-digit character or eof. Fails if the number has more
106 // digits than max_digits or if there is no number.
107 fn read_number<T: ReadNumberHelper>(
108 &mut self,
109 radix: u32,
110 max_digits: Option<usize>,
111 allow_zero_prefix: bool,
112 ) -> Option<T> {
113 self.read_atomically(move |p| {
114 let mut result = T::ZERO;
115 let mut digit_count = 0;
116 let has_leading_zero = p.peek_char() == Some('0');
117
118 while let Some(digit) = p.read_atomically(|p| p.read_char()?.to_digit(radix)) {
119 result = result.checked_mul(radix)?;
120 result = result.checked_add(digit)?;
121 digit_count += 1;
122 if let Some(max_digits) = max_digits {
123 if digit_count > max_digits {
124 return None;
125 }
126 }
127 }
128
129 if digit_count == 0 {
130 None
131 } else if !allow_zero_prefix && has_leading_zero && digit_count > 1 {
132 None
133 } else {
134 Some(result)
135 }
136 })
137 }
138
139 /// Read an IPv4 address.
140 fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
141 self.read_atomically(|p| {
142 let mut groups = [0; 4];
143
144 for (i, slot) in groups.iter_mut().enumerate() {
145 *slot = p.read_separator('.', i, |p| {
146 // Disallow octal number in IP string.
147 // https://tools.ietf.org/html/rfc6943#section-3.1.1
148 p.read_number(10, Some(3), false)
149 })?;
150 }
151
152 Some(groups.into())
153 })
154 }
155
156 /// Read an IPv6 Address.
157 fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
158 /// Read a chunk of an IPv6 address into `groups`. Returns the number
159 /// of groups read, along with a bool indicating if an embedded
160 /// trailing IPv4 address was read. Specifically, read a series of
161 /// colon-separated IPv6 groups (0x0000 - 0xFFFF), with an optional
162 /// trailing embedded IPv4 address.
163 fn read_groups(p: &mut Parser<'_>, groups: &mut [u16]) -> (usize, bool) {
164 let limit = groups.len();
165
166 for (i, slot) in groups.iter_mut().enumerate() {
167 // Try to read a trailing embedded IPv4 address. There must be
168 // at least two groups left.
169 if i < limit - 1 {
170 let ipv4 = p.read_separator(':', i, |p| p.read_ipv4_addr());
171
172 if let Some(v4_addr) = ipv4 {
173 let [one, two, three, four] = v4_addr.octets();
174 groups[i + 0] = u16::from_be_bytes([one, two]);
175 groups[i + 1] = u16::from_be_bytes([three, four]);
176 return (i + 2, true);
177 }
178 }
179
180 let group = p.read_separator(':', i, |p| p.read_number(16, Some(4), true));
181
182 match group {
183 Some(g) => *slot = g,
184 None => return (i, false),
185 }
186 }
187 (groups.len(), false)
188 }
189
190 self.read_atomically(|p| {
191 // Read the front part of the address; either the whole thing, or up
192 // to the first ::
193 let mut head = [0; 8];
194 let (head_size, head_ipv4) = read_groups(p, &mut head);
195
196 if head_size == 8 {
197 return Some(head.into());
198 }
199
200 // IPv4 part is not allowed before `::`
201 if head_ipv4 {
202 return None;
203 }
204
205 // Read `::` if previous code parsed less than 8 groups.
206 // `::` indicates one or more groups of 16 bits of zeros.
207 p.read_given_char(':')?;
208 p.read_given_char(':')?;
209
210 // Read the back part of the address. The :: must contain at least one
211 // set of zeroes, so our max length is 7.
212 let mut tail = [0; 7];
213 let limit = 8 - (head_size + 1);
214 let (tail_size, _) = read_groups(p, &mut tail[..limit]);
215
216 // Concat the head and tail of the IP address
217 head[(8 - tail_size)..8].copy_from_slice(&tail[..tail_size]);
218
219 Some(head.into())
220 })
221 }
222
223 /// Read an IP Address, either IPv4 or IPv6.
224 fn read_ip_addr(&mut self) -> Option<IpAddr> {
225 self.read_ipv4_addr().map(IpAddr::V4).or_else(move || self.read_ipv6_addr().map(IpAddr::V6))
226 }
227
228 /// Read a `:` followed by a port in base 10.
229 fn read_port(&mut self) -> Option<u16> {
230 self.read_atomically(|p| {
231 p.read_given_char(':')?;
232 p.read_number(10, None, true)
233 })
234 }
235
236 /// Read a `%` followed by a scope ID in base 10.
237 fn read_scope_id(&mut self) -> Option<u32> {
238 self.read_atomically(|p| {
239 p.read_given_char('%')?;
240 p.read_number(10, None, true)
241 })
242 }
243
244 /// Read an IPv4 address with a port.
245 fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
246 self.read_atomically(|p| {
247 let ip = p.read_ipv4_addr()?;
248 let port = p.read_port()?;
249 Some(SocketAddrV4::new(ip, port))
250 })
251 }
252
253 /// Read an IPv6 address with a port.
254 fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
255 self.read_atomically(|p| {
256 p.read_given_char('[')?;
257 let ip = p.read_ipv6_addr()?;
258 let scope_id = p.read_scope_id().unwrap_or(0);
259 p.read_given_char(']')?;
260
261 let port = p.read_port()?;
262 Some(SocketAddrV6::new(ip, port, 0, scope_id))
263 })
264 }
265
266 /// Read an IP address with a port
267 fn read_socket_addr(&mut self) -> Option<SocketAddr> {
268 self.read_socket_addr_v4()
269 .map(SocketAddr::V4)
270 .or_else(|| self.read_socket_addr_v6().map(SocketAddr::V6))
271 }
272}
273
274impl IpAddr {
275 /// Parse an IP address from a slice of bytes.
276 ///
277 /// ```
278 /// #![feature(addr_parse_ascii)]
279 ///
280 /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
281 ///
282 /// let localhost_v4 = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
283 /// let localhost_v6 = IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1));
284 ///
285 /// assert_eq!(IpAddr::parse_ascii(b"127.0.0.1"), Ok(localhost_v4));
286 /// assert_eq!(IpAddr::parse_ascii(b"::1"), Ok(localhost_v6));
287 /// ```
288 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
289 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
290 Parser::new(b).parse_with(|p| p.read_ip_addr(), kind:AddrKind::Ip)
291 }
292}
293
294#[stable(feature = "ip_addr", since = "1.7.0")]
295impl FromStr for IpAddr {
296 type Err = AddrParseError;
297 fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
298 Self::parse_ascii(s.as_bytes())
299 }
300}
301
302impl Ipv4Addr {
303 /// Parse an IPv4 address from a slice of bytes.
304 ///
305 /// ```
306 /// #![feature(addr_parse_ascii)]
307 ///
308 /// use std::net::Ipv4Addr;
309 ///
310 /// let localhost = Ipv4Addr::new(127, 0, 0, 1);
311 ///
312 /// assert_eq!(Ipv4Addr::parse_ascii(b"127.0.0.1"), Ok(localhost));
313 /// ```
314 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
315 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
316 // don't try to parse if too long
317 if b.len() > 15 {
318 Err(AddrParseError(AddrKind::Ipv4))
319 } else {
320 Parser::new(b).parse_with(|p| p.read_ipv4_addr(), kind:AddrKind::Ipv4)
321 }
322 }
323}
324
325#[stable(feature = "rust1", since = "1.0.0")]
326impl FromStr for Ipv4Addr {
327 type Err = AddrParseError;
328 fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
329 Self::parse_ascii(s.as_bytes())
330 }
331}
332
333impl Ipv6Addr {
334 /// Parse an IPv6 address from a slice of bytes.
335 ///
336 /// ```
337 /// #![feature(addr_parse_ascii)]
338 ///
339 /// use std::net::Ipv6Addr;
340 ///
341 /// let localhost = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1);
342 ///
343 /// assert_eq!(Ipv6Addr::parse_ascii(b"::1"), Ok(localhost));
344 /// ```
345 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
346 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
347 Parser::new(b).parse_with(|p| p.read_ipv6_addr(), kind:AddrKind::Ipv6)
348 }
349}
350
351#[stable(feature = "rust1", since = "1.0.0")]
352impl FromStr for Ipv6Addr {
353 type Err = AddrParseError;
354 fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
355 Self::parse_ascii(s.as_bytes())
356 }
357}
358
359impl SocketAddrV4 {
360 /// Parse an IPv4 socket address from a slice of bytes.
361 ///
362 /// ```
363 /// #![feature(addr_parse_ascii)]
364 ///
365 /// use std::net::{Ipv4Addr, SocketAddrV4};
366 ///
367 /// let socket = SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080);
368 ///
369 /// assert_eq!(SocketAddrV4::parse_ascii(b"127.0.0.1:8080"), Ok(socket));
370 /// ```
371 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
372 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
373 Parser::new(b).parse_with(|p| p.read_socket_addr_v4(), kind:AddrKind::SocketV4)
374 }
375}
376
377#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
378impl FromStr for SocketAddrV4 {
379 type Err = AddrParseError;
380 fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
381 Self::parse_ascii(s.as_bytes())
382 }
383}
384
385impl SocketAddrV6 {
386 /// Parse an IPv6 socket address from a slice of bytes.
387 ///
388 /// ```
389 /// #![feature(addr_parse_ascii)]
390 ///
391 /// use std::net::{Ipv6Addr, SocketAddrV6};
392 ///
393 /// let socket = SocketAddrV6::new(Ipv6Addr::new(0x2001, 0xdb8, 0, 0, 0, 0, 0, 1), 8080, 0, 0);
394 ///
395 /// assert_eq!(SocketAddrV6::parse_ascii(b"[2001:db8::1]:8080"), Ok(socket));
396 /// ```
397 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
398 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
399 Parser::new(b).parse_with(|p| p.read_socket_addr_v6(), kind:AddrKind::SocketV6)
400 }
401}
402
403#[stable(feature = "socket_addr_from_str", since = "1.5.0")]
404impl FromStr for SocketAddrV6 {
405 type Err = AddrParseError;
406 fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
407 Self::parse_ascii(s.as_bytes())
408 }
409}
410
411impl SocketAddr {
412 /// Parse a socket address from a slice of bytes.
413 ///
414 /// ```
415 /// #![feature(addr_parse_ascii)]
416 ///
417 /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
418 ///
419 /// let socket_v4 = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 8080);
420 /// let socket_v6 = SocketAddr::new(IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)), 8080);
421 ///
422 /// assert_eq!(SocketAddr::parse_ascii(b"127.0.0.1:8080"), Ok(socket_v4));
423 /// assert_eq!(SocketAddr::parse_ascii(b"[::1]:8080"), Ok(socket_v6));
424 /// ```
425 #[unstable(feature = "addr_parse_ascii", issue = "101035")]
426 pub fn parse_ascii(b: &[u8]) -> Result<Self, AddrParseError> {
427 Parser::new(b).parse_with(|p| p.read_socket_addr(), kind:AddrKind::Socket)
428 }
429}
430
431#[stable(feature = "rust1", since = "1.0.0")]
432impl FromStr for SocketAddr {
433 type Err = AddrParseError;
434 fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
435 Self::parse_ascii(s.as_bytes())
436 }
437}
438
439#[derive(Debug, Clone, PartialEq, Eq)]
440enum AddrKind {
441 Ip,
442 Ipv4,
443 Ipv6,
444 Socket,
445 SocketV4,
446 SocketV6,
447}
448
449/// An error which can be returned when parsing an IP address or a socket address.
450///
451/// This error is used as the error type for the [`FromStr`] implementation for
452/// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
453/// [`SocketAddrV6`].
454///
455/// # Potential causes
456///
457/// `AddrParseError` may be thrown because the provided string does not parse as the given type,
458/// often because it includes information only handled by a different address type.
459///
460/// ```should_panic
461/// use std::net::IpAddr;
462/// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
463/// ```
464///
465/// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
466///
467/// ```
468/// use std::net::SocketAddr;
469///
470/// // No problem, the `panic!` message has disappeared.
471/// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
472/// ```
473#[stable(feature = "rust1", since = "1.0.0")]
474#[derive(Debug, Clone, PartialEq, Eq)]
475pub struct AddrParseError(AddrKind);
476
477#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
478impl fmt::Display for AddrParseError {
479 #[allow(deprecated, deprecated_in_future)]
480 fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
481 fmt.write_str(self.description())
482 }
483}
484
485#[stable(feature = "addr_parse_error_error", since = "1.4.0")]
486impl Error for AddrParseError {
487 #[allow(deprecated)]
488 fn description(&self) -> &str {
489 match self.0 {
490 AddrKind::Ip => "invalid IP address syntax",
491 AddrKind::Ipv4 => "invalid IPv4 address syntax",
492 AddrKind::Ipv6 => "invalid IPv6 address syntax",
493 AddrKind::Socket => "invalid socket address syntax",
494 AddrKind::SocketV4 => "invalid IPv4 socket address syntax",
495 AddrKind::SocketV6 => "invalid IPv6 socket address syntax",
496 }
497 }
498}
499