@@ -69,12 +69,13 @@ impl Authority {
69
69
// Postcondition: for all Ok() returns, s[..ret.unwrap()] is valid UTF-8 where
70
70
// ret is the return value.
71
71
pub ( super ) fn parse ( s : & [ u8 ] ) -> Result < usize , InvalidUri > {
72
- let mut colon_cnt = 0 ;
72
+ let mut colon_cnt = 0u32 ;
73
73
let mut start_bracket = false ;
74
74
let mut end_bracket = false ;
75
75
let mut has_percent = false ;
76
76
let mut end = s. len ( ) ;
77
77
let mut at_sign_pos = None ;
78
+ const MAX_COLONS : u32 = 8 ; // e.g., [FEDC:BA98:7654:3210:FEDC:BA98:7654:3210]:80
78
79
79
80
// Among other things, this loop checks that every byte in s up to the
80
81
// first '/', '?', or '#' is a valid URI character (or in some contexts,
@@ -87,6 +88,9 @@ impl Authority {
87
88
break ;
88
89
}
89
90
b':' => {
91
+ if colon_cnt >= MAX_COLONS {
92
+ return Err ( ErrorKind :: InvalidAuthority . into ( ) ) ;
93
+ }
90
94
colon_cnt += 1 ;
91
95
}
92
96
b'[' => {
@@ -644,6 +648,12 @@ mod tests {
644
648
assert_eq ! ( result, authority_str) ;
645
649
}
646
650
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
+
647
657
#[ test]
648
658
fn rejects_percent_outside_ipv6_address ( ) {
649
659
let err = Authority :: parse_non_empty ( b"1234%20[fe80::1:2:3:4]" ) . unwrap_err ( ) ;
0 commit comments