@@ -329,7 +329,7 @@ fn longest_zero_sequence(pieces: &[u16; 8]) -> (isize, isize) {
329
329
}
330
330
331
331
/// <https://url.spec.whatwg.org/#ipv4-number-parser>
332
- fn parse_ipv4number ( mut input : & str ) -> Result < u32 , ( ) > {
332
+ fn parse_ipv4number ( mut input : & str ) -> Result < Option < u32 > , ( ) > {
333
333
let mut r = 10 ;
334
334
if input. starts_with ( "0x" ) || input. starts_with ( "0X" ) {
335
335
input = & input[ 2 ..] ;
@@ -338,14 +338,30 @@ fn parse_ipv4number(mut input: &str) -> Result<u32, ()> {
338
338
input = & input[ 1 ..] ;
339
339
r = 8 ;
340
340
}
341
+
342
+ // At the moment we can't know the reason why from_str_radix fails
343
+ // https://github.com/rust-lang/rust/issues/22639
344
+ // So instead we check if the input looks like a real number and only return
345
+ // an error when it's an overflow.
346
+ let valid_number = match r {
347
+ 8 => input. chars ( ) . all ( |c| c >= '0' && c <='7' ) ,
348
+ 10 => input. chars ( ) . all ( |c| c >= '0' && c <='9' ) ,
349
+ 16 => input. chars ( ) . all ( |c| ( c >= '0' && c <='9' ) || ( c >='a' && c <= 'f' ) || ( c >= 'A' && c <= 'F' ) ) ,
350
+ _ => false
351
+ } ;
352
+
353
+ if !valid_number {
354
+ return Ok ( None ) ;
355
+ }
356
+
341
357
if input. is_empty ( ) {
342
- return Ok ( 0 ) ;
358
+ return Ok ( Some ( 0 ) ) ;
343
359
}
344
360
if input. starts_with ( '+' ) {
345
- return Err ( ( ) )
361
+ return Ok ( None ) ;
346
362
}
347
363
match u32:: from_str_radix ( input, r) {
348
- Ok ( number) => Ok ( number) ,
364
+ Ok ( number) => Ok ( Some ( number) ) ,
349
365
Err ( _) => Err ( ( ) ) ,
350
366
}
351
367
}
@@ -363,15 +379,19 @@ fn parse_ipv4addr(input: &str) -> ParseResult<Option<Ipv4Addr>> {
363
379
return Ok ( None ) ;
364
380
}
365
381
let mut numbers: Vec < u32 > = Vec :: new ( ) ;
382
+ let mut overflow = false ;
366
383
for part in parts {
367
384
if part == "" {
368
385
return Ok ( None ) ;
369
386
}
370
- if let Ok ( n) = parse_ipv4number ( part) {
371
- numbers. push ( n) ;
372
- } else {
373
- return Ok ( None ) ;
374
- }
387
+ match parse_ipv4number ( part) {
388
+ Ok ( Some ( n) ) => numbers. push ( n) ,
389
+ Ok ( None ) => return Ok ( None ) ,
390
+ Err ( ( ) ) => overflow = true
391
+ } ;
392
+ }
393
+ if overflow {
394
+ return Err ( ParseError :: InvalidIpv4Address ) ;
375
395
}
376
396
let mut ipv4 = numbers. pop ( ) . expect ( "a non-empty list of numbers" ) ;
377
397
// Equivalent to: ipv4 >= 256 ** (4 − numbers.len())
0 commit comments