@@ -423,6 +423,9 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
423
423
return Err ( ParseError :: InvalidIpv6Address )
424
424
}
425
425
i = start;
426
+ if piece_pointer > 6 {
427
+ return Err ( ParseError :: InvalidIpv6Address )
428
+ }
426
429
is_ip_v4 = true ;
427
430
} ,
428
431
b':' => {
@@ -445,16 +448,24 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
445
448
if piece_pointer > 6 {
446
449
return Err ( ParseError :: InvalidIpv6Address )
447
450
}
448
- let mut dots_seen = 0 ;
451
+ let mut numbers_seen = 0 ;
449
452
while i < len {
450
- let mut value = None ;
453
+ if numbers_seen > 0 {
454
+ if numbers_seen < 4 && ( i < len && input[ i] == b'.' ) {
455
+ i += 1
456
+ } else {
457
+ return Err ( ParseError :: InvalidIpv6Address )
458
+ }
459
+ }
460
+
461
+ let mut ipv4_piece = None ;
451
462
while i < len {
452
463
let digit = match input[ i] {
453
464
c @ b'0' ... b'9' => c - b'0' ,
454
465
_ => break
455
466
} ;
456
- match value {
457
- None => value = Some ( digit as u16 ) ,
467
+ match ipv4_piece {
468
+ None => ipv4_piece = Some ( digit as u16 ) ,
458
469
Some ( 0 ) => return Err ( ParseError :: InvalidIpv6Address ) , // No leading zero
459
470
Some ( ref mut v) => {
460
471
* v = * v * 10 + digit as u16 ;
@@ -465,24 +476,28 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
465
476
}
466
477
i += 1 ;
467
478
}
468
- if dots_seen < 3 && !( i < len && input[ i] == b'.' ) {
469
- return Err ( ParseError :: InvalidIpv6Address )
470
- }
471
- pieces[ piece_pointer] = if let Some ( v) = value {
479
+
480
+ pieces[ piece_pointer] = if let Some ( v) = ipv4_piece {
472
481
pieces[ piece_pointer] * 0x100 + v
473
482
} else {
474
483
return Err ( ParseError :: InvalidIpv6Address )
475
484
} ;
476
- if dots_seen == 1 || dots_seen == 3 {
485
+ numbers_seen += 1 ;
486
+
487
+ if numbers_seen == 2 || numbers_seen == 4 {
477
488
piece_pointer += 1 ;
478
489
}
479
- i += 1 ;
480
- if dots_seen == 3 && i < len {
481
- return Err ( ParseError :: InvalidIpv6Address )
482
- }
483
- dots_seen += 1 ;
490
+ }
491
+
492
+ if numbers_seen != 4 {
493
+ return Err ( ParseError :: InvalidIpv6Address )
484
494
}
485
495
}
496
+
497
+ if i < len {
498
+ return Err ( ParseError :: InvalidIpv6Address )
499
+ }
500
+
486
501
match compress_pointer {
487
502
Some ( compress_pointer) => {
488
503
let mut swaps = piece_pointer - compress_pointer;
0 commit comments