@@ -69,12 +69,13 @@ impl Authority {
6969 // Postcondition: for all Ok() returns, s[..ret.unwrap()] is valid UTF-8 where
7070 // ret is the return value.
7171 pub ( super ) fn parse ( s : & [ u8 ] ) -> Result < usize , InvalidUri > {
72- let mut colon_cnt = 0 ;
72+ let mut colon_cnt = 0u32 ;
7373 let mut start_bracket = false ;
7474 let mut end_bracket = false ;
7575 let mut has_percent = false ;
7676 let mut end = s. len ( ) ;
7777 let mut at_sign_pos = None ;
78+ const MAX_COLONS : u32 = 8 ; // e.g., [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80
7879
7980 // Among other things, this loop checks that every byte in s up to the
8081 // first '/', '?', or '#' is a valid URI character (or in some contexts,
@@ -87,6 +88,9 @@ impl Authority {
8788 break ;
8889 }
8990 b':' => {
91+ if colon_cnt >= MAX_COLONS {
92+ return Err ( ErrorKind :: InvalidAuthority . into ( ) ) ;
93+ }
9094 colon_cnt += 1 ;
9195 }
9296 b'[' => {
@@ -644,6 +648,12 @@ mod tests {
644648 assert_eq ! ( result, authority_str) ;
645649 }
646650
651+ #[ test]
652+ fn reject_obviously_invalid_ipv6_address ( ) {
653+ let err = Authority :: parse_non_empty ( b"[0:1:2:3:4:5:6:7:8:9:10:11:12:13:14]" ) . unwrap_err ( ) ;
654+ assert_eq ! ( err. 0 , ErrorKind :: InvalidAuthority ) ;
655+ }
656+
647657 #[ test]
648658 fn rejects_percent_outside_ipv6_address ( ) {
649659 let err = Authority :: parse_non_empty ( b"1234%20[fe80::1:2:3:4]" ) . unwrap_err ( ) ;
0 commit comments