]> git.lizzy.rs Git - rust.git/blob - src/libstd/net/parser.rs
Format libstd/sys with rustfmt
[rust.git] / src / libstd / net / parser.rs
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
6 use crate::error::Error;
7 use crate::fmt;
8 use crate::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
9 use crate::str::FromStr;
10
11 struct Parser<'a> {
12     // parsing as ASCII, so can use byte array
13     s: &'a [u8],
14     pos: usize,
15 }
16
17 impl<'a> Parser<'a> {
18     fn new(s: &'a str) -> Parser<'a> {
19         Parser {
20             s: s.as_bytes(),
21             pos: 0,
22         }
23     }
24
25     fn is_eof(&self) -> bool {
26         self.pos == self.s.len()
27     }
28
29     // Commit only if parser returns Some
30     fn read_atomically<T, F>(&mut self, cb: F) -> Option<T> where
31         F: FnOnce(&mut Parser<'_>) -> Option<T>,
32     {
33         let pos = self.pos;
34         let r = cb(self);
35         if r.is_none() {
36             self.pos = pos;
37         }
38         r
39     }
40
41     // Commit only if parser read till EOF
42     fn read_till_eof<T, F>(&mut self, cb: F) -> Option<T> where
43         F: FnOnce(&mut Parser<'_>) -> Option<T>,
44     {
45         self.read_atomically(move |p| {
46             cb(p).filter(|_| p.is_eof())
47         })
48     }
49
50     // Return result of first successful parser
51     fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser<'_>) -> Option<T> + 'static>])
52                -> Option<T> {
53         for pf in parsers {
54             if let Some(r) = self.read_atomically(|p: &mut Parser<'_>| pf(p)) {
55                 return Some(r);
56             }
57         }
58         None
59     }
60
61     // Apply 3 parsers sequentially
62     fn read_seq_3<A, B, C, PA, PB, PC>(&mut self,
63                                        pa: PA,
64                                        pb: PB,
65                                        pc: PC)
66                                        -> Option<(A, B, C)> where
67         PA: FnOnce(&mut Parser<'_>) -> Option<A>,
68         PB: FnOnce(&mut Parser<'_>) -> Option<B>,
69         PC: FnOnce(&mut Parser<'_>) -> Option<C>,
70     {
71         self.read_atomically(move |p| {
72             let a = pa(p);
73             let b = if a.is_some() { pb(p) } else { None };
74             let c = if b.is_some() { pc(p) } else { None };
75             match (a, b, c) {
76                 (Some(a), Some(b), Some(c)) => Some((a, b, c)),
77                 _ => None
78             }
79         })
80     }
81
82     // Read next char
83     fn read_char(&mut self) -> Option<char> {
84         if self.is_eof() {
85             None
86         } else {
87             let r = self.s[self.pos] as char;
88             self.pos += 1;
89             Some(r)
90         }
91     }
92
93     // Return char and advance iff next char is equal to requested
94     fn read_given_char(&mut self, c: char) -> Option<char> {
95         self.read_atomically(|p| {
96             match p.read_char() {
97                 Some(next) if next == c => Some(next),
98                 _ => None,
99             }
100         })
101     }
102
103     // Read digit
104     fn read_digit(&mut self, radix: u8) -> Option<u8> {
105         fn parse_digit(c: char, radix: u8) -> Option<u8> {
106             let c = c as u8;
107             // assuming radix is either 10 or 16
108             if c >= b'0' && c <= b'9' {
109                 Some(c - b'0')
110             } else if radix > 10 && c >= b'a' && c < b'a' + (radix - 10) {
111                 Some(c - b'a' + 10)
112             } else if radix > 10 && c >= b'A' && c < b'A' + (radix - 10) {
113                 Some(c - b'A' + 10)
114             } else {
115                 None
116             }
117         }
118
119         self.read_atomically(|p| {
120             p.read_char().and_then(|c| parse_digit(c, radix))
121         })
122     }
123
124     fn read_number_impl(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
125         let mut r = 0;
126         let mut digit_count = 0;
127         loop {
128             match self.read_digit(radix) {
129                 Some(d) => {
130                     r = r * (radix as u32) + (d as u32);
131                     digit_count += 1;
132                     if digit_count > max_digits || r >= upto {
133                         return None
134                     }
135                 }
136                 None => {
137                     if digit_count == 0 {
138                         return None
139                     } else {
140                         return Some(r)
141                     }
142                 }
143             };
144         }
145     }
146
147     // Read number, failing if max_digits of number value exceeded
148     fn read_number(&mut self, radix: u8, max_digits: u32, upto: u32) -> Option<u32> {
149         self.read_atomically(|p| p.read_number_impl(radix, max_digits, upto))
150     }
151
152     fn read_ipv4_addr_impl(&mut self) -> Option<Ipv4Addr> {
153         let mut bs = [0; 4];
154         let mut i = 0;
155         while i < 4 {
156             if i != 0 && self.read_given_char('.').is_none() {
157                 return None;
158             }
159
160             bs[i] = self.read_number(10, 3, 0x100).map(|n| n as u8)?;
161             i += 1;
162         }
163         Some(Ipv4Addr::new(bs[0], bs[1], bs[2], bs[3]))
164     }
165
166     // Read IPv4 address
167     fn read_ipv4_addr(&mut self) -> Option<Ipv4Addr> {
168         self.read_atomically(|p| p.read_ipv4_addr_impl())
169     }
170
171     fn read_ipv6_addr_impl(&mut self) -> Option<Ipv6Addr> {
172         fn ipv6_addr_from_head_tail(head: &[u16], tail: &[u16]) -> Ipv6Addr {
173             assert!(head.len() + tail.len() <= 8);
174             let mut gs = [0; 8];
175             gs[..head.len()].copy_from_slice(head);
176             gs[(8 - tail.len()) .. 8].copy_from_slice(tail);
177             Ipv6Addr::new(gs[0], gs[1], gs[2], gs[3], gs[4], gs[5], gs[6], gs[7])
178         }
179
180         fn read_groups(p: &mut Parser<'_>, groups: &mut [u16; 8], limit: usize)
181                        -> (usize, bool) {
182             let mut i = 0;
183             while i < limit {
184                 if i < limit - 1 {
185                     let ipv4 = p.read_atomically(|p| {
186                         if i == 0 || p.read_given_char(':').is_some() {
187                             p.read_ipv4_addr()
188                         } else {
189                             None
190                         }
191                     });
192                     if let Some(v4_addr) = ipv4 {
193                         let octets = v4_addr.octets();
194                         groups[i + 0] = ((octets[0] as u16) << 8) | (octets[1] as u16);
195                         groups[i + 1] = ((octets[2] as u16) << 8) | (octets[3] as u16);
196                         return (i + 2, true);
197                     }
198                 }
199
200                 let group = p.read_atomically(|p| {
201                     if i == 0 || p.read_given_char(':').is_some() {
202                         p.read_number(16, 4, 0x10000).map(|n| n as u16)
203                     } else {
204                         None
205                     }
206                 });
207                 match group {
208                     Some(g) => groups[i] = g,
209                     None => return (i, false)
210                 }
211                 i += 1;
212             }
213             (i, false)
214         }
215
216         let mut head = [0; 8];
217         let (head_size, head_ipv4) = read_groups(self, &mut head, 8);
218
219         if head_size == 8 {
220             return Some(Ipv6Addr::new(
221                 head[0], head[1], head[2], head[3],
222                 head[4], head[5], head[6], head[7]))
223         }
224
225         // IPv4 part is not allowed before `::`
226         if head_ipv4 {
227             return None
228         }
229
230         // read `::` if previous code parsed less than 8 groups
231         if !self.read_given_char(':').is_some() || !self.read_given_char(':').is_some() {
232             return None;
233         }
234
235         let mut tail = [0; 8];
236         // `::` indicates one or more groups of 16 bits of zeros
237         let limit = 8 - (head_size + 1);
238         let (tail_size, _) = read_groups(self, &mut tail, limit);
239         Some(ipv6_addr_from_head_tail(&head[..head_size], &tail[..tail_size]))
240     }
241
242     fn read_ipv6_addr(&mut self) -> Option<Ipv6Addr> {
243         self.read_atomically(|p| p.read_ipv6_addr_impl())
244     }
245
246     fn read_ip_addr(&mut self) -> Option<IpAddr> {
247         let ipv4_addr = |p: &mut Parser<'_>| p.read_ipv4_addr().map(IpAddr::V4);
248         let ipv6_addr = |p: &mut Parser<'_>| p.read_ipv6_addr().map(IpAddr::V6);
249         self.read_or(&mut [Box::new(ipv4_addr), Box::new(ipv6_addr)])
250     }
251
252     fn read_socket_addr_v4(&mut self) -> Option<SocketAddrV4> {
253         let ip_addr = |p: &mut Parser<'_>| p.read_ipv4_addr();
254         let colon = |p: &mut Parser<'_>| p.read_given_char(':');
255         let port = |p: &mut Parser<'_>| {
256             p.read_number(10, 5, 0x10000).map(|n| n as u16)
257         };
258
259         self.read_seq_3(ip_addr, colon, port).map(|t| {
260             let (ip, _, port): (Ipv4Addr, char, u16) = t;
261             SocketAddrV4::new(ip, port)
262         })
263     }
264
265     fn read_socket_addr_v6(&mut self) -> Option<SocketAddrV6> {
266         let ip_addr = |p: &mut Parser<'_>| {
267             let open_br = |p: &mut Parser<'_>| p.read_given_char('[');
268             let ip_addr = |p: &mut Parser<'_>| p.read_ipv6_addr();
269             let clos_br = |p: &mut Parser<'_>| p.read_given_char(']');
270             p.read_seq_3(open_br, ip_addr, clos_br).map(|t| t.1)
271         };
272         let colon = |p: &mut Parser<'_>| p.read_given_char(':');
273         let port = |p: &mut Parser<'_>| {
274             p.read_number(10, 5, 0x10000).map(|n| n as u16)
275         };
276
277         self.read_seq_3(ip_addr, colon, port).map(|t| {
278             let (ip, _, port): (Ipv6Addr, char, u16) = t;
279             SocketAddrV6::new(ip, port, 0, 0)
280         })
281     }
282
283     fn read_socket_addr(&mut self) -> Option<SocketAddr> {
284         let v4 = |p: &mut Parser<'_>| p.read_socket_addr_v4().map(SocketAddr::V4);
285         let v6 = |p: &mut Parser<'_>| p.read_socket_addr_v6().map(SocketAddr::V6);
286         self.read_or(&mut [Box::new(v4), Box::new(v6)])
287     }
288 }
289
290 #[stable(feature = "ip_addr", since = "1.7.0")]
291 impl FromStr for IpAddr {
292     type Err = AddrParseError;
293     fn from_str(s: &str) -> Result<IpAddr, AddrParseError> {
294         match Parser::new(s).read_till_eof(|p| p.read_ip_addr()) {
295             Some(s) => Ok(s),
296             None => Err(AddrParseError(()))
297         }
298     }
299 }
300
301 #[stable(feature = "rust1", since = "1.0.0")]
302 impl FromStr for Ipv4Addr {
303     type Err = AddrParseError;
304     fn from_str(s: &str) -> Result<Ipv4Addr, AddrParseError> {
305         match Parser::new(s).read_till_eof(|p| p.read_ipv4_addr()) {
306             Some(s) => Ok(s),
307             None => Err(AddrParseError(()))
308         }
309     }
310 }
311
312 #[stable(feature = "rust1", since = "1.0.0")]
313 impl FromStr for Ipv6Addr {
314     type Err = AddrParseError;
315     fn from_str(s: &str) -> Result<Ipv6Addr, AddrParseError> {
316         match Parser::new(s).read_till_eof(|p| p.read_ipv6_addr()) {
317             Some(s) => Ok(s),
318             None => Err(AddrParseError(()))
319         }
320     }
321 }
322
323 #[stable(feature = "socket_addr_from_str", since = "1.5.0")]
324 impl FromStr for SocketAddrV4 {
325     type Err = AddrParseError;
326     fn from_str(s: &str) -> Result<SocketAddrV4, AddrParseError> {
327         match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v4()) {
328             Some(s) => Ok(s),
329             None => Err(AddrParseError(())),
330         }
331     }
332 }
333
334 #[stable(feature = "socket_addr_from_str", since = "1.5.0")]
335 impl FromStr for SocketAddrV6 {
336     type Err = AddrParseError;
337     fn from_str(s: &str) -> Result<SocketAddrV6, AddrParseError> {
338         match Parser::new(s).read_till_eof(|p| p.read_socket_addr_v6()) {
339             Some(s) => Ok(s),
340             None => Err(AddrParseError(())),
341         }
342     }
343 }
344
345 #[stable(feature = "rust1", since = "1.0.0")]
346 impl FromStr for SocketAddr {
347     type Err = AddrParseError;
348     fn from_str(s: &str) -> Result<SocketAddr, AddrParseError> {
349         match Parser::new(s).read_till_eof(|p| p.read_socket_addr()) {
350             Some(s) => Ok(s),
351             None => Err(AddrParseError(())),
352         }
353     }
354 }
355
356 /// An error which can be returned when parsing an IP address or a socket address.
357 ///
358 /// This error is used as the error type for the [`FromStr`] implementation for
359 /// [`IpAddr`], [`Ipv4Addr`], [`Ipv6Addr`], [`SocketAddr`], [`SocketAddrV4`], and
360 /// [`SocketAddrV6`].
361 ///
362 /// # Potential causes
363 ///
364 /// `AddrParseError` may be thrown because the provided string does not parse as the given type,
365 /// often because it includes information only handled by a different address type.
366 ///
367 /// ```should_panic
368 /// use std::net::IpAddr;
369 /// let _foo: IpAddr = "127.0.0.1:8080".parse().expect("Cannot handle the socket port");
370 /// ```
371 ///
372 /// [`IpAddr`] doesn't handle the port. Use [`SocketAddr`] instead.
373 ///
374 /// ```
375 /// use std::net::SocketAddr;
376 ///
377 /// // No problem, the `panic!` message has disappeared.
378 /// let _foo: SocketAddr = "127.0.0.1:8080".parse().expect("unreachable panic");
379 /// ```
380 ///
381 /// [`FromStr`]: ../../std/str/trait.FromStr.html
382 /// [`IpAddr`]: ../../std/net/enum.IpAddr.html
383 /// [`Ipv4Addr`]: ../../std/net/struct.Ipv4Addr.html
384 /// [`Ipv6Addr`]: ../../std/net/struct.Ipv6Addr.html
385 /// [`SocketAddr`]: ../../std/net/enum.SocketAddr.html
386 /// [`SocketAddrV4`]: ../../std/net/struct.SocketAddrV4.html
387 /// [`SocketAddrV6`]: ../../std/net/struct.SocketAddrV6.html
388 #[stable(feature = "rust1", since = "1.0.0")]
389 #[derive(Debug, Clone, PartialEq, Eq)]
390 pub struct AddrParseError(());
391
392 #[stable(feature = "addr_parse_error_error", since = "1.4.0")]
393 impl fmt::Display for AddrParseError {
394     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
395         fmt.write_str(self.description())
396     }
397 }
398
399 #[stable(feature = "addr_parse_error_error", since = "1.4.0")]
400 impl Error for AddrParseError {
401     fn description(&self) -> &str {
402         "invalid IP address syntax"
403     }
404 }