From 2ca0057efe74e7b34c7575807ef3e9dfb9697435 Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Mon, 27 Jul 2026 06:28:04 +0900 Subject: [PATCH 1/2] add a failing test --- src/grapheme.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/grapheme.rs b/src/grapheme.rs index c006eb9..be5a076 100644 --- a/src/grapheme.rs +++ b/src/grapheme.rs @@ -847,6 +847,25 @@ impl GraphemeCursor { } } +#[test] +fn test_grapheme_cursor_ris_count_across_chunks() { + use GraphemeIncomplete::*; + + let chunk0 = "a"; // 1 byte + let chunk1 = "\u{1f1e6}"; // 4 bytes + let chunk2 = "\u{1f1e6}"; // 4 bytes + let full_len = chunk0.len() + chunk1.len() + chunk2.len(); // 9 + let chunk1_start = chunk0.len(); + let chunk2_start = chunk0.len() + chunk1.len(); + + let mut c = GraphemeCursor::new(0, full_len, true); + assert_eq!(c.next_boundary(chunk0, 0), Err(NextChunk)); + assert_eq!(c.next_boundary(chunk1, chunk1_start), Ok(Some(1))); + assert_eq!(c.next_boundary(chunk1, chunk1_start), Err(NextChunk)); + assert_eq!(c.next_boundary(chunk2, chunk2_start), Ok(Some(9))); + assert_eq!(c.next_boundary(chunk2, chunk2_start), Ok(None)); +} + #[test] fn test_grapheme_cursor_ris_precontext() { let s = "\u{1f1fa}\u{1f1f8}\u{1f1fa}\u{1f1f8}\u{1f1fa}\u{1f1f8}"; From 2b73855fa8abe502679e7e9ede9e34ebdbead58e Mon Sep 17 00:00:00 2001 From: Hyeseong Kim Date: Mon, 27 Jul 2026 06:31:21 +0900 Subject: [PATCH 2/2] fix --- src/grapheme.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/grapheme.rs b/src/grapheme.rs index be5a076..d33a351 100644 --- a/src/grapheme.rs +++ b/src/grapheme.rs @@ -623,7 +623,10 @@ impl GraphemeCursor { let mut need_pre_context = true; match self.cat_after.unwrap() { gr::GC_InCB_Consonant => self.state = GraphemeState::InCbConsonant, - gr::GC_Regional_Indicator => self.state = GraphemeState::Regional, + // Only look back for the RI count if it isn't known already. + gr::GC_Regional_Indicator if self.ris_count.is_none() => { + self.state = GraphemeState::Regional + } gr::GC_Extended_Pictographic => { self.state = GraphemeState::Emoji { seen_zwj: false } }