Skip to content

Commit b00473c

Browse files
authored
Return an error rather than panicking when HeaderName is too long (#433)
Fixes #432. This eliminates an undocumented panic from the `HeaderName` creation functions, returning instead an `InvalidHeaderName` when the name length exceeds `MAX_HEADER_NAME_LEN`. I considered making `InvalidHeaderName` a richer error type, but since it was already used for another type of length error (rejecting zero-length names) I figured it was okay to reuse. I also redefined `MAX_HEADER_NAME_LEN` slightly, so that it is equal to the largest allowed header length, rather than one past that value. This was motivated by discovering a bug in my comparison logic when I went to write the new test exercising the wrong-length error conditions.
1 parent 975dbdd commit b00473c

2 files changed

Lines changed: 27 additions & 14 deletions

File tree

src/header/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,4 @@ pub use self::name::{
169169
/// Generally, 64kb for a header name is WAY too much than would ever be needed
170170
/// in practice. Restricting it to this size enables using `u16` values to
171171
/// represent offsets when dealing with header names.
172-
const MAX_HEADER_NAME_LEN: usize = 1 << 16;
172+
const MAX_HEADER_NAME_LEN: usize = (1 << 16) - 1;

src/header/name.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,10 +1116,6 @@ fn parse_hdr<'a>(
11161116
($d:ident, $src:ident, 35) => { to_lower!($d, $src, 34); $d[34] = table[$src[34] as usize]; };
11171117
}
11181118

1119-
assert!(len < super::MAX_HEADER_NAME_LEN,
1120-
"header name too long -- max length is {}",
1121-
super::MAX_HEADER_NAME_LEN);
1122-
11231119
match len {
11241120
0 => Err(InvalidHeaderName::new()),
11251121
2 => {
@@ -1509,17 +1505,16 @@ fn parse_hdr<'a>(
15091505
validate(b, len)
15101506
}
15111507
}
1512-
_ => {
1513-
if len < 64 {
1514-
for i in 0..len {
1515-
b[i] = table[data[i] as usize];
1516-
}
1517-
1518-
validate(b, len)
1519-
} else {
1520-
Ok(HdrName::custom(data, false))
1508+
len if len < 64 => {
1509+
for i in 0..len {
1510+
b[i] = table[data[i] as usize];
15211511
}
1512+
validate(b, len)
1513+
}
1514+
len if len <= super::MAX_HEADER_NAME_LEN => {
1515+
Ok(HdrName::custom(data, false))
15221516
}
1517+
_ => Err(InvalidHeaderName::new()),
15231518
}
15241519
}
15251520

@@ -2156,6 +2151,24 @@ mod tests {
21562151
}
21572152
}
21582153

2154+
#[test]
2155+
fn test_invalid_name_lengths() {
2156+
assert!(
2157+
HeaderName::from_bytes(&[]).is_err(),
2158+
"zero-length header name is an error",
2159+
);
2160+
let mut long = vec![b'a'; super::super::MAX_HEADER_NAME_LEN];
2161+
assert!(
2162+
HeaderName::from_bytes(long.as_slice()).is_ok(),
2163+
"max header name length is ok",
2164+
);
2165+
long.push(b'a');
2166+
assert!(
2167+
HeaderName::from_bytes(long.as_slice()).is_err(),
2168+
"longer than max header name length is an error",
2169+
);
2170+
}
2171+
21592172
#[test]
21602173
fn test_from_hdr_name() {
21612174
use self::StandardHeader::Vary;

0 commit comments

Comments
 (0)