Allow '[' and ']' in URI paths.

This is strictly noncompliant and they should be encoded, but browsers
routinely send them unencoded, so we allow them to avoid trouble.
This commit is contained in:
Sergio Benitez 2022-05-04 09:20:13 -07:00
parent 4c6c0b497c
commit ee4aa81847
4 changed files with 11 additions and 4 deletions

View File

@ -146,7 +146,7 @@ fn host<'a>(
input: &mut RawInput<'a>,
) -> Result<'a, Extent<&'a [u8]>> {
switch! {
peek(b'[') => enclosed(b'[', is_pchar, b']')?,
peek(b'[') => enclosed(b'[', is_host_char, b']')?,
_ => take_while(is_reg_name_char)?
}
}

View File

@ -58,7 +58,11 @@ const USER_INFO_CHARS: [u8; 256] = char_table(&[
]);
pub const PATH_CHARS: [u8; 256] = char_table(&[
&REG_NAME_CHARS, &[b':', b'@', b'/']
&REG_NAME_CHARS, &[b':', b'@', b'/'],
// NOTE: these are _not_ accepted in RFC 7230/3986. However, browsers
// routinely send these unencoded, so allow them to support the real-world.
&[b'[', b']'],
]);
const QUERY_CHARS: [u8; 256] = char_table(&[
@ -72,6 +76,9 @@ const QUERY_CHARS: [u8; 256] = char_table(&[
#[inline(always)]
pub const fn is_pchar(&c: &u8) -> bool { PATH_CHARS[c as usize] != 0 }
#[inline(always)]
pub const fn is_host_char(c: &u8) -> bool { is_pchar(c) && *c != b'[' && *c != b']' }
#[inline(always)]
pub const fn is_scheme_char(&c: &u8) -> bool { SCHEME_CHAR[c as usize] != 0 }

View File

@ -143,7 +143,7 @@ fn single_byte() {
"@" => Authority::new("", "", None),
);
assert_no_parse!("[", "]");
assert_no_parse!["\\", "^"];
}
#[test]

View File

@ -31,7 +31,7 @@ mod tests {
#[test]
fn uri_percent_encoding_redirect() {
let expected_location = vec!["/hello/John%5B%5D%7C%5C%25@%5E"];
let expected_location = vec!["/hello/John[]%7C%5C%25@%5E"];
let client = Client::debug(rocket()).unwrap();
let response = client.get("/raw").dispatch();