From 76e0e5b0ac1a186ca3c9aad3e1ba6d6f1a97be13 Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Mon, 26 Oct 2026 21:22:36 +0000 Subject: [PATCH] Only treat % plus two hex digits as an escape in MCP resource URIs Found while testing crates/mcp/src/resources.rs:169 (decode) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/mcp/src/resources.rs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/crates/mcp/src/resources.rs b/crates/mcp/src/resources.rs index f22b45959..704c3392e 100644 --- a/crates/mcp/src/resources.rs +++ b/crates/mcp/src/resources.rs @@ -166,6 +166,8 @@ fn decode(s: &str) -> String { while let Some(b) = bytes.get(i).copied() { if b == b'%' && i + 2 < bytes.len() + && let Some(digits) = bytes.get(i + 1..i + 3) + && digits.iter().all(u8::is_ascii_hexdigit) && let Ok(byte) = u8::from_str_radix(s.get(i + 1..i + 3).unwrap_or(""), 16) { out.push(byte); @@ -211,6 +213,15 @@ const MAX_CATALOGUE: usize = 20_000; mod tests { use super::*; + #[test] + fn decode_only_accepts_two_hex_digits() { + assert_eq!(decode("a%+1b"), "a%+1b"); + assert_eq!(decode("a%-1b"), "a%-1b"); + assert_eq!(decode("a%+Fb"), "a%+Fb"); + assert_eq!(decode("a%4"), "a%4"); + assert_eq!(decode("Brand%2040%25"), "Brand 40%"); + } + #[test] fn variables_are_split_out_and_decoded() { assert_eq!(variable("vectorcraft://object/42", "vectorcraft://object/{id}"), "42");