From c97ca226e6e5f1e1139d9cf670108f3e25fb0fda Mon Sep 17 00:00:00 2001 From: NetterSilver <133535268+Silvertree2010@users.noreply.github.com> Date: Thu, 15 Oct 2026 08:58:15 +0200 Subject: [PATCH] Fix util.printd panic on an escaped multi-byte character (#2386) Found while testing crates/js/src/lib.rs:785 Co-authored-by: Claude Haiku 5.5 --- crates/js/src/lib.rs | 6 ++++-- crates/js/src/tests.rs | 11 +++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/crates/js/src/lib.rs b/crates/js/src/lib.rs index ef2fc0594..d8d9fa8ba 100644 --- a/crates/js/src/lib.rs +++ b/crates/js/src/lib.rs @@ -783,8 +783,10 @@ fn printd(_: &JsValue, args: &[JsValue], ctx: &mut Context) -> JsResult out.push_str(if run >= 2 { ampm } else { &m[..1] }); } b'\\' if i + 1 < b.len() => { - out.push(b[i + 1] as char); - i += 2; + // The escaped character may be multi-byte; copy it whole. + let ch = fmt[i + 1..].chars().next().unwrap_or(' '); + out.push(ch); + i += 1 + ch.len_utf8(); continue; } _ => { diff --git a/crates/js/src/tests.rs b/crates/js/src/tests.rs index c8ee81218..3521c6d07 100644 --- a/crates/js/src/tests.rs +++ b/crates/js/src/tests.rs @@ -94,6 +94,17 @@ fn util_printf_printd_and_printx() { assert_eq!(o.value, "1,234,567.89|00042|hi|FF|1.234,50|Jan 5, 2024 09:07|Friday|(555) 123-4567|ABC"); } +#[test] +fn printd_escapes_multibyte_chars() { + let o = go( + "event.value = [util.printd('yyyy \\\\é', new Date(2024, 0, 5)), util.printd('\\\\€ yyyy', new Date(2024, 0, 5)), \ + util.printd('\\\\y yyyy', new Date(2024, 0, 5))].join('|');", + &Event::field("Calculate", "total", ""), + ); + assert_eq!(o.error, None); + assert_eq!(o.value, "2024 é|€ 2024|y 2024"); +} + fn assert_printf_error(script: &str, message: &str) { let o = go(script, &Event::doc("Open")); assert!(o.error.as_deref().is_some_and(|e| e.starts_with(message)), "{script}: {:?}", o.error);