@@ -423,6 +423,9 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
423423 return Err ( ParseError :: InvalidIpv6Address )
424424 }
425425 i = start;
426+ if piece_pointer > 6 {
427+ return Err ( ParseError :: InvalidIpv6Address )
428+ }
426429 is_ip_v4 = true ;
427430 } ,
428431 b':' => {
@@ -445,16 +448,24 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
445448 if piece_pointer > 6 {
446449 return Err ( ParseError :: InvalidIpv6Address )
447450 }
448- let mut dots_seen = 0 ;
451+ let mut numbers_seen = 0 ;
449452 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 ;
451462 while i < len {
452463 let digit = match input[ i] {
453464 c @ b'0' ... b'9' => c - b'0' ,
454465 _ => break
455466 } ;
456- match value {
457- None => value = Some ( digit as u16 ) ,
467+ match ipv4_piece {
468+ None => ipv4_piece = Some ( digit as u16 ) ,
458469 Some ( 0 ) => return Err ( ParseError :: InvalidIpv6Address ) , // No leading zero
459470 Some ( ref mut v) => {
460471 * v = * v * 10 + digit as u16 ;
@@ -465,24 +476,28 @@ fn parse_ipv6addr(input: &str) -> ParseResult<Ipv6Addr> {
465476 }
466477 i += 1 ;
467478 }
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 {
472481 pieces[ piece_pointer] * 0x100 + v
473482 } else {
474483 return Err ( ParseError :: InvalidIpv6Address )
475484 } ;
476- if dots_seen == 1 || dots_seen == 3 {
485+ numbers_seen += 1 ;
486+
487+ if numbers_seen == 2 || numbers_seen == 4 {
477488 piece_pointer += 1 ;
478489 }
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 )
484494 }
485495 }
496+
497+ if i < len {
498+ return Err ( ParseError :: InvalidIpv6Address )
499+ }
500+
486501 match compress_pointer {
487502 Some ( compress_pointer) => {
488503 let mut swaps = piece_pointer - compress_pointer;
0 commit comments