From 2872b5cd79f1cd6555a6b53690ee38e5d847528b Mon Sep 17 00:00:00 2001 From: salmonik Date: Wed, 4 Nov 2026 01:32:15 +0100 Subject: web: percent-encode UTF-8 query bytes --- src/commands/web.rs | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/commands/web.rs b/src/commands/web.rs index f8b8667..fc44d7b 100644 --- a/src/commands/web.rs +++ b/src/commands/web.rs @@ -111,15 +111,30 @@ fn url_decode(s: &str) -> String { } fn urlencoding(s: &str) -> String { - s.chars() - .map(|c| match c { - 'A'..='Z' | 'a'..='z' | '0'..='9' | '_' | '-' | '.' | '~' => c.to_string(), - ' ' => "+".to_string(), - _ => format!("%{:02X}", c as u8), - }) - .collect() + let mut out = String::with_capacity(s.len()); + for byte in s.as_bytes() { + match byte { + b'A'..=b'Z' | b'a'..=b'z' | b'0'..=b'9' | b'_' | b'-' | b'.' | b'~' => { + out.push(*byte as char) + } + b' ' => out.push('+'), + _ => out.push_str(&format!("%{byte:02X}")), + } + } + out } pub fn commands() -> Vec> { vec![web()] } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn encodes_utf8_bytes_not_chars() { + assert_eq!(urlencoding("ż"), "%C5%BC"); + assert_eq!(urlencoding("a b"), "a+b"); + } +} -- cgit v1.2.3