From d4aa281666167aaee3e7376a36deba10fbe5ba18 Mon Sep 17 00:00:00 2001 From: duongynhi000005-oss Date: Thu, 5 Nov 2026 09:07:15 +0700 Subject: [PATCH] fix(uri): reject unconsumed trailing bytes in Authority::from_static `validate_authority_bytes` stops at the first `/`, `?`, or `#` delimiter and returns the end index of the authority segment. While `create_authority` checks `authority_end != s.len()`, `Authority::from_static` matched `Ok(_)` and discarded the returned offset, allowing strings with a scheme prefix or trailing path/query/fragment (such as `"https://127.0.0.1"`) to construct an invalid `Authority`. Require `Ok(end) if end == src.len()` in `Authority::from_static` so its validation matches `Authority::from_str`. Fixes #879 Signed-off-by: duongynhi000005-oss --- src/uri/authority.rs | 35 +++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/uri/authority.rs b/src/uri/authority.rs index c5479cb24..79bcbff9e 100644 --- a/src/uri/authority.rs +++ b/src/uri/authority.rs @@ -48,8 +48,7 @@ impl Authority { /// /// # Panics /// - /// This function panics if the argument contains invalid characters or - /// is empty. + /// This function panics if the argument is not a valid authority. /// /// # Examples /// @@ -61,10 +60,10 @@ impl Authority { #[inline] pub const fn from_static(src: &'static str) -> Self { match validate_authority_bytes(src.as_bytes()) { - Ok(_) => Authority { + Ok(end) if end == src.len() => Authority { data: ByteStr::from_static(src), }, - Err(_) => panic!("static str is not valid authority"), + _ => panic!("static str is not valid authority"), } } @@ -722,4 +721,32 @@ mod tests { let err = Authority::parse_non_empty(b"]o[").unwrap_err(); assert_eq!(err.0, ErrorKind::InvalidAuthority); } + + #[test] + #[should_panic(expected = "static str is not valid authority")] + fn from_static_rejects_scheme_prefix() { + assert!("https://127.0.0.1".parse::().is_err()); + Authority::from_static("https://127.0.0.1"); + } + + #[test] + #[should_panic(expected = "static str is not valid authority")] + fn from_static_rejects_trailing_path() { + assert!("example.com/path".parse::().is_err()); + Authority::from_static("example.com/path"); + } + + #[test] + #[should_panic(expected = "static str is not valid authority")] + fn from_static_rejects_trailing_query() { + assert!("example.com?query=1".parse::().is_err()); + Authority::from_static("example.com?query=1"); + } + + #[test] + #[should_panic(expected = "static str is not valid authority")] + fn from_static_rejects_trailing_fragment() { + assert!("example.com#frag".parse::().is_err()); + Authority::from_static("example.com#frag"); + } }