Skip to content

Commit d3cae7c

Browse files
avitexseanmonstar
authored andcommitted
Fix parsing of long host with no scheme (#351)
This change fixes an issue where an URI with no scheme, a host part with a length greater than the max for a scheme, while only consisting of valid characters for a scheme would fail to parse. Rather than assuming the string being parsed is meant to contain a scheme and returning an error if the max length for a scheme is met, we instead extract the scheme part if it exists and validate its length. The trade-off is worse performance in the error case of a scheme that is too long.
1 parent 8ffe094 commit d3cae7c

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/uri/scheme.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -336,10 +336,6 @@ impl Scheme2<usize> {
336336
for i in 0..s.len() {
337337
let b = s[i];
338338

339-
if i == MAX_SCHEME_LEN {
340-
return Err(ErrorKind::SchemeTooLong.into());
341-
}
342-
343339
match SCHEME_CHARS[b as usize] {
344340
b':' => {
345341
// Not enough data remaining
@@ -352,6 +348,10 @@ impl Scheme2<usize> {
352348
break;
353349
}
354350

351+
if i > MAX_SCHEME_LEN {
352+
return Err(ErrorKind::SchemeTooLong.into());
353+
}
354+
355355
// Return scheme
356356
return Ok(Scheme2::Other(i));
357357
}

src/uri/tests.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,30 @@ test_parse! {
231231
port_part = None,
232232
}
233233

234+
test_parse! {
235+
test_uri_parse_long_host_with_no_scheme,
236+
"thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost",
237+
[],
238+
239+
scheme_part = None,
240+
authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost"),
241+
path = "",
242+
query = None,
243+
port_part = None,
244+
}
245+
246+
test_parse! {
247+
test_uri_parse_long_host_with_port_and_no_scheme,
248+
"thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234",
249+
[],
250+
251+
scheme_part = None,
252+
authority_part = part!("thequickbrownfoxjumpedoverthelazydogtofindthelargedangerousdragon.localhost:1234"),
253+
path = "",
254+
query = None,
255+
port_part = Port::from_str("1234").ok(),
256+
}
257+
234258
test_parse! {
235259
test_userinfo1,
236260
"http://a:[email protected]:1234/",
@@ -430,7 +454,7 @@ fn test_max_uri_len() {
430454
}
431455

432456
#[test]
433-
fn test_long_scheme() {
457+
fn test_overflowing_scheme() {
434458
let mut uri = vec![];
435459
uri.extend(vec![b'a'; 256]);
436460
uri.extend(b"://localhost/");
@@ -441,6 +465,18 @@ fn test_long_scheme() {
441465
assert_eq!(res.unwrap_err().0, ErrorKind::SchemeTooLong);
442466
}
443467

468+
#[test]
469+
fn test_max_length_scheme() {
470+
let mut uri = vec![];
471+
uri.extend(vec![b'a'; 64]);
472+
uri.extend(b"://localhost/");
473+
474+
let uri = String::from_utf8(uri).unwrap();
475+
let uri: Uri = uri.parse().unwrap();
476+
477+
assert_eq!(uri.scheme_str().unwrap().len(), 64);
478+
}
479+
444480
#[test]
445481
fn test_uri_to_path_and_query() {
446482
let cases = vec![

0 commit comments

Comments
 (0)