@@ -12,7 +12,7 @@ use crate::fmt;
12
12
use crate :: net:: { IpAddr , Ipv4Addr , Ipv6Addr , SocketAddr , SocketAddrV4 , SocketAddrV6 } ;
13
13
use crate :: str:: FromStr ;
14
14
15
- trait ReadNumberHelper : crate :: marker:: Sized {
15
+ trait ReadNumberHelper : crate :: marker:: Sized + crate :: cmp :: PartialEq {
16
16
const ZERO : Self ;
17
17
fn checked_mul ( & self , other : u32 ) -> Option < Self > ;
18
18
fn checked_add ( & self , other : u32 ) -> Option < Self > ;
@@ -111,10 +111,12 @@ impl<'a> Parser<'a> {
111
111
& mut self ,
112
112
radix : u32 ,
113
113
max_digits : Option < usize > ,
114
+ allow_zero_prefix : bool ,
114
115
) -> Option < T > {
115
116
self . read_atomically ( move |p| {
116
117
let mut result = T :: ZERO ;
117
118
let mut digit_count = 0 ;
119
+ let has_leading_zero = p. peek_char ( ) == Some ( '0' ) ;
118
120
119
121
while let Some ( digit) = p. read_atomically ( |p| p. read_char ( ) ?. to_digit ( radix) ) {
120
122
result = result. checked_mul ( radix) ?;
@@ -127,7 +129,16 @@ impl<'a> Parser<'a> {
127
129
}
128
130
}
129
131
130
- if digit_count == 0 { None } else { Some ( result) }
132
+ if digit_count == 0 {
133
+ None
134
+ } else if !allow_zero_prefix
135
+ && has_leading_zero
136
+ && ( result != T :: ZERO || result == T :: ZERO && digit_count > 1 )
137
+ {
138
+ None
139
+ } else {
140
+ Some ( result)
141
+ }
131
142
} )
132
143
}
133
144
@@ -140,10 +151,7 @@ impl<'a> Parser<'a> {
140
151
* slot = p. read_separator ( '.' , i, |p| {
141
152
// Disallow octal number in IP string.
142
153
// https://tools.ietf.org/html/rfc6943#section-3.1.1
143
- match ( p. peek_char ( ) , p. read_number ( 10 , None ) ) {
144
- ( Some ( '0' ) , Some ( number) ) if number != 0 => None ,
145
- ( _, number) => number,
146
- }
154
+ p. read_number ( 10 , None , false )
147
155
} ) ?;
148
156
}
149
157
@@ -175,7 +183,7 @@ impl<'a> Parser<'a> {
175
183
}
176
184
}
177
185
178
- let group = p. read_separator ( ':' , i, |p| p. read_number ( 16 , Some ( 4 ) ) ) ;
186
+ let group = p. read_separator ( ':' , i, |p| p. read_number ( 16 , Some ( 4 ) , true ) ) ;
179
187
180
188
match group {
181
189
Some ( g) => * slot = g,
@@ -227,15 +235,15 @@ impl<'a> Parser<'a> {
227
235
fn read_port ( & mut self ) -> Option < u16 > {
228
236
self . read_atomically ( |p| {
229
237
p. read_given_char ( ':' ) ?;
230
- p. read_number ( 10 , None )
238
+ p. read_number ( 10 , None , true )
231
239
} )
232
240
}
233
241
234
242
/// Read a `%` followed by a scope ID in base 10.
235
243
fn read_scope_id ( & mut self ) -> Option < u32 > {
236
244
self . read_atomically ( |p| {
237
245
p. read_given_char ( '%' ) ?;
238
- p. read_number ( 10 , None )
246
+ p. read_number ( 10 , None , true )
239
247
} )
240
248
}
241
249
0 commit comments