fix(header): fix panic when parsing header names larger than 64kb
This commit is contained in:
@@ -104,7 +104,7 @@ impl Http1Transaction for Server {
|
|||||||
Version::HTTP_10
|
Version::HTTP_10
|
||||||
};
|
};
|
||||||
|
|
||||||
record_header_indices(bytes, &req.headers, &mut headers_indices);
|
record_header_indices(bytes, &req.headers, &mut headers_indices)?;
|
||||||
headers_len = req.headers.len();
|
headers_len = req.headers.len();
|
||||||
//(len, subject, version, headers_len)
|
//(len, subject, version, headers_len)
|
||||||
}
|
}
|
||||||
@@ -590,7 +590,7 @@ impl Http1Transaction for Client {
|
|||||||
} else {
|
} else {
|
||||||
Version::HTTP_10
|
Version::HTTP_10
|
||||||
};
|
};
|
||||||
record_header_indices(bytes, &res.headers, &mut headers_indices);
|
record_header_indices(bytes, &res.headers, &mut headers_indices)?;
|
||||||
let headers_len = res.headers.len();
|
let headers_len = res.headers.len();
|
||||||
(len, status, version, headers_len)
|
(len, status, version, headers_len)
|
||||||
},
|
},
|
||||||
@@ -918,7 +918,11 @@ struct HeaderIndices {
|
|||||||
value: (usize, usize),
|
value: (usize, usize),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn record_header_indices(bytes: &[u8], headers: &[httparse::Header], indices: &mut [HeaderIndices]) {
|
fn record_header_indices(
|
||||||
|
bytes: &[u8],
|
||||||
|
headers: &[httparse::Header],
|
||||||
|
indices: &mut [HeaderIndices]
|
||||||
|
) -> Result<(), ::error::Parse> {
|
||||||
let bytes_ptr = bytes.as_ptr() as usize;
|
let bytes_ptr = bytes.as_ptr() as usize;
|
||||||
|
|
||||||
// FIXME: This should be a single plain `for` loop.
|
// FIXME: This should be a single plain `for` loop.
|
||||||
@@ -945,6 +949,10 @@ fn record_header_indices(bytes: &[u8], headers: &[httparse::Header], indices: &m
|
|||||||
cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon"))
|
cfg(all(target_arch = "arm", target_feature = "v7", target_feature = "neon"))
|
||||||
for (header, indices) in (headers.iter().zip(indices.iter_mut())) {
|
for (header, indices) in (headers.iter().zip(indices.iter_mut())) {
|
||||||
{
|
{
|
||||||
|
if header.name.len() >= (1 << 16) {
|
||||||
|
debug!("header name larger than 64kb: {:?}", header.name);
|
||||||
|
return Err(::error::Parse::TooLarge);
|
||||||
|
}
|
||||||
let name_start = header.name.as_ptr() as usize - bytes_ptr;
|
let name_start = header.name.as_ptr() as usize - bytes_ptr;
|
||||||
let name_end = name_start + header.name.len();
|
let name_end = name_start + header.name.len();
|
||||||
indices.name = (name_start, name_end);
|
indices.name = (name_start, name_end);
|
||||||
@@ -956,6 +964,8 @@ fn record_header_indices(bytes: &[u8], headers: &[httparse::Header], indices: &m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write header names as title case. The header name is assumed to be ASCII,
|
// Write header names as title case. The header name is assumed to be ASCII,
|
||||||
|
|||||||
@@ -1024,6 +1024,24 @@ fn returning_1xx_response_is_error() {
|
|||||||
rt.block_on(fut).expect_err("1xx status code should error");
|
rt.block_on(fut).expect_err("1xx status code should error");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn header_name_too_long() {
|
||||||
|
let server = serve();
|
||||||
|
|
||||||
|
let mut req = connect(server.addr());
|
||||||
|
let mut write = Vec::with_capacity(1024 * 66);
|
||||||
|
write.extend_from_slice(b"GET / HTTP/1.1\r\n");
|
||||||
|
for _ in 0..(1024 * 65) {
|
||||||
|
write.push(b'x');
|
||||||
|
}
|
||||||
|
write.extend_from_slice(b": foo\r\n\r\n");
|
||||||
|
req.write_all(&write).unwrap();
|
||||||
|
|
||||||
|
let mut buf = [0; 1024];
|
||||||
|
let n = req.read(&mut buf).unwrap();
|
||||||
|
assert!(s(&buf[..n]).starts_with("HTTP/1.1 431 Request Header Fields Too Large\r\n"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn upgrades() {
|
fn upgrades() {
|
||||||
use tokio_io::io::{read_to_end, write_all};
|
use tokio_io::io::{read_to_end, write_all};
|
||||||
|
|||||||
Reference in New Issue
Block a user