From bffaeb85c63dce6776518a5099949093037e8c16 Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 6 Oct 2025 14:05:31 +0200 Subject: [PATCH 1/2] Fix roundtripping issue --- url/src/host.rs | 29 ++++++++++++++++++++--------- url/tests/unit.rs | 9 +++++++++ 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/url/src/host.rs b/url/src/host.rs index 7911d328..a8e98e5a 100644 --- a/url/src/host.rs +++ b/url/src/host.rs @@ -151,16 +151,27 @@ impl<'a> Host> { }; if input.find(is_invalid_host_char).is_some() { - Err(ParseError::InvalidDomainCharacter) - } else { - Ok(Host::Domain( - match utf8_percent_encode(&input, CONTROLS).into() { - Cow::Owned(v) => Cow::Owned(v), - // if we're borrowing, then we can return the original Cow - Cow::Borrowed(_) => input, - }, - )) + return Err(ParseError::InvalidDomainCharacter); } + + // Call utf8_percent_encode and use the result. + // Note: This returns Cow::Borrowed for single-item results (either from input + // or from the static encoding table), and Cow::Owned for multi-item results. + // We cannot distinguish between "borrowed from input" vs "borrowed from static table" + // based on the Cow variant alone. + Ok(Host::Domain( + match utf8_percent_encode(&input, CONTROLS).into() { + Cow::Owned(v) => Cow::Owned(v), + // If we're borrowing, we need to check if it's the same as the input + Cow::Borrowed(v) => { + if v == &*input { + input // No encoding happened, reuse original + } else { + Cow::Owned(v.to_owned()) // Borrowed from static table, need to own it + } + } + }, + )) } pub(crate) fn into_owned(self) -> Host { diff --git a/url/tests/unit.rs b/url/tests/unit.rs index 9422a195..828f7975 100644 --- a/url/tests/unit.rs +++ b/url/tests/unit.rs @@ -1383,3 +1383,12 @@ fn serde_error_message() { r#"relative URL without a base: "§invalid#+#*Ä" at line 1 column 25"# ); } + +#[test] +fn test_parse_url_with_single_byte_control_host() { + let input = "l://\x01:"; + + let url1 = Url::parse(input).unwrap(); + let url2 = Url::parse(url1.as_str()).unwrap(); + assert_eq!(url2, url1); +} From 810f8861370805fc3d97298d230309a89e4a2ece Mon Sep 17 00:00:00 2001 From: Valentin Gosu Date: Mon, 6 Oct 2025 14:15:55 +0200 Subject: [PATCH 2/2] Skip running doctests with sanitizer due to mixing will cause an ABI mismatch in crate --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3d3b2499..2e912151 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -100,7 +100,7 @@ jobs: echo "Running tests with $sanitizer sanitizer..." export RUSTFLAGS="-Z sanitizer=$sanitizer" export RUSTDOCFLAGS="$RUSTFLAGS" - cargo +nightly test -Z build-std --target "$TARGET" + cargo +nightly test -Z build-std --target "$TARGET" --lib --tests done WASM: