From 392e68dbe68076451f34ee95c99d5e622f18f824 Mon Sep 17 00:00:00 2001 From: Sean Kim <40130483+theskim@users.noreply.github.com> Date: Tue, 17 Dec 2024 17:22:06 -0500 Subject: [PATCH] Handle updating the hostname when the first path segment is empty --- url/src/lib.rs | 9 ++++++++- url/tests/expected_failures.txt | 2 -- url/tests/unit.rs | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/url/src/lib.rs b/url/src/lib.rs index bea5b3da..3d12c47d 100644 --- a/url/src/lib.rs +++ b/url/src/lib.rs @@ -2129,7 +2129,7 @@ impl Url { } else { self.host_end }; - let suffix = self.slice(old_suffix_pos..).to_owned(); + let mut suffix = self.slice(old_suffix_pos..).to_owned(); self.serialization.truncate(self.host_start as usize); if !self.has_authority() { debug_assert!(self.slice(self.scheme_end..self.host_start) == ":"); @@ -2143,6 +2143,13 @@ impl Url { self.host_end = to_u32(self.serialization.len()).unwrap(); self.host = host.into(); + // Adjust serialization to switch from host to empty segment + if suffix.starts_with("/.//") { + suffix.drain(.."/.".len()); + // pathname should be "//p" not "p" given that the first segment was empty + self.path_start -= "//".len() as u32; + } + if let Some(new_port) = opt_new_port { self.port = new_port; if let Some(port) = new_port { diff --git a/url/tests/expected_failures.txt b/url/tests/expected_failures.txt index d1ed726c..9bf60b34 100644 --- a/url/tests/expected_failures.txt +++ b/url/tests/expected_failures.txt @@ -36,8 +36,6 @@ set hostname to set hostname to - set hostname to - set hostname to <> set pathname to <> set href to set pathname to <\\\\> diff --git a/url/tests/unit.rs b/url/tests/unit.rs index fe9745d9..4dc8f051 100644 --- a/url/tests/unit.rs +++ b/url/tests/unit.rs @@ -1422,6 +1422,7 @@ fn test_fuzzing_uri_failures() { #[test] fn test_can_be_a_base_with_set_path() { + use url::quirks; let mut url = Url::parse("web+demo:/").unwrap(); assert!(!url.cannot_be_a_base()); @@ -1436,6 +1437,10 @@ fn test_can_be_a_base_with_set_path() { assert_eq!(segments, vec!["", "not-a-host"]); assert_eq!(url.as_str(), "web+demo:/.//not-a-host"); + quirks::set_hostname(&mut url, "test").unwrap(); + assert_eq!(url.as_str(), "web+demo://test//not-a-host"); + quirks::set_hostname(&mut url, "").unwrap(); + assert_eq!(url.as_str(), "web+demo:////not-a-host"); } #[test]