From ee248bb5cbdbee5e97916f415409dc6c2a38f84f Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Sat, 24 Oct 2026 07:18:46 +0000 Subject: [PATCH] Decode numeric tab entities in HTML paste Found while testing crates/engine/src/cmd/richclip.rs:304 (numeric_char, used by decode_text) Co-Authored-By: Claude Haiku 5.5 Co-Authored-By: Claude Sonnet 5.5 --- crates/engine/src/cmd/richclip.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/crates/engine/src/cmd/richclip.rs b/crates/engine/src/cmd/richclip.rs index 8b21b4bb..2abec7d2 100644 --- a/crates/engine/src/cmd/richclip.rs +++ b/crates/engine/src/cmd/richclip.rs @@ -334,7 +334,7 @@ fn decode_text(raw: &str) -> String { fn numeric_char(digits: &str) -> Option { let hex = digits.strip_prefix('x').or_else(|| digits.strip_prefix('X')); let n = if let Some(hex) = hex { u32::from_str_radix(hex, 16).ok()? } else { digits.parse().ok()? }; - char::from_u32(n).filter(|c| !c.is_control() || *c == '\n') + char::from_u32(n).filter(|c| !c.is_control() || matches!(*c, '\n' | '\t')) } /// Do the HTML's words and the paste's plain text say the same thing? @@ -352,6 +352,12 @@ fn fold(s: &str) -> String { mod tests { use super::*; + #[test] + fn numeric_tab_entity_decodes_to_tab() { + assert_eq!(decode_text("a b"), "a\tb"); + assert_eq!(decode_text("a b"), "a\tb"); + } + #[test] fn google_docs_normal_weight_wrapper_is_not_bold() { let html = "plain words";