fix(headers): add length checks to ETag parsing

Bug found using `cargo fuzz`.
This commit is contained in:
Pyfisch
2017-03-05 12:40:06 +01:00
parent d80aae55b1
commit 643fac1e01
2 changed files with 8 additions and 3 deletions

View File

@@ -83,6 +83,9 @@ header! {
test_header!(test14, test_header!(test14,
vec![b"matched-\"dquotes\""], vec![b"matched-\"dquotes\""],
None::<ETag>); None::<ETag>);
test_header!(test15,
vec![b"\""],
None::<ETag>);
} }
} }

View File

@@ -123,15 +123,17 @@ impl FromStr for EntityTag {
let length: usize = s.len(); let length: usize = s.len();
let slice = &s[..]; let slice = &s[..];
// Early exits if it doesn't terminate in a DQUOTE. // Early exits if it doesn't terminate in a DQUOTE.
if !slice.ends_with('"') { if !slice.ends_with('"') || slice.len() < 2 {
return Err(::Error::Header); return Err(::Error::Header);
} }
// The etag is weak if its first char is not a DQUOTE. // The etag is weak if its first char is not a DQUOTE.
if slice.starts_with('"') && check_slice_validity(&slice[1..length-1]) { if slice.len() >= 2 && slice.starts_with('"')
&& check_slice_validity(&slice[1..length-1]) {
// No need to check if the last char is a DQUOTE, // No need to check if the last char is a DQUOTE,
// we already did that above. // we already did that above.
return Ok(EntityTag { weak: false, tag: slice[1..length-1].to_owned() }); return Ok(EntityTag { weak: false, tag: slice[1..length-1].to_owned() });
} else if slice.starts_with("W/\"") && check_slice_validity(&slice[3..length-1]) { } else if slice.len() >= 4 && slice.starts_with("W/\"")
&& check_slice_validity(&slice[3..length-1]) {
return Ok(EntityTag { weak: true, tag: slice[3..length-1].to_owned() }); return Ok(EntityTag { weak: true, tag: slice[3..length-1].to_owned() });
} }
Err(::Error::Header) Err(::Error::Header)