From aa06a9db84174a71df4a487d0b42e197faec64c3 Mon Sep 17 00:00:00 2001 From: Edward Langley Date: Mon, 21 Sep 2026 10:19:14 -0700 Subject: [PATCH] improvise-711n: pin that a multibyte format string cannot split a char boundary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `format:` is `rest_of_line` in `improv.pest`, so the format string can hold any text. `leading_digits` slices at the byte index `str::find` returns, which is a char boundary by construction — but that is an argument, and this is the test. It also pins that a non-ASCII digit (U+0662) names no precision rather than one. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01FC2jVn8Au7E9JPkw6bwXXH --- crates/improvise-core/src/format.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/crates/improvise-core/src/format.rs b/crates/improvise-core/src/format.rs index ef5dfb60..cbc1909a 100644 --- a/crates/improvise-core/src/format.rs +++ b/crates/improvise-core/src/format.rs @@ -131,6 +131,15 @@ mod tests { assert_eq!(parse_number_format(",.999f"), (true, 0)); } + /// `format:` is `rest_of_line` in the grammar, so the format string can hold + /// any text at all — including a multibyte char right after the dot. + #[test] + fn a_multibyte_character_after_the_dot_does_not_split_a_char_boundary() { + assert_eq!(parse_number_format(",.2\u{20ac}"), (true, 2)); + assert_eq!(parse_number_format(".\u{20ac}"), (false, 0)); + assert_eq!(parse_number_format(".\u{0662}"), (false, 0)); + } + #[test] fn a_format_naming_no_precision_at_all_reads_as_zero() { assert_eq!(parse_number_format(",f"), (true, 0));