diff --git a/src/buffer/mod.rs b/src/buffer/mod.rs index 499e2dd82ad7..4676fb945b93 100644 --- a/src/buffer/mod.rs +++ b/src/buffer/mod.rs @@ -1152,7 +1152,7 @@ impl TextBuffer { fn find_select_next(&mut self, search: &mut ActiveSearch, offset: usize, wrap: bool) { if search.buffer_generation != self.buffer.generation() { - unsafe { search.regex.set_text(&search.text, offset) }; + unsafe { search.regex.set_text(&mut search.text, offset) }; search.buffer_generation = self.buffer.generation(); search.next_search_offset = offset; } else if search.next_search_offset != offset { diff --git a/src/icu.rs b/src/icu.rs index d8f36a7d084d..a82b653d8253 100644 --- a/src/icu.rs +++ b/src/icu.rs @@ -628,7 +628,12 @@ impl Regex { /// # Safety /// /// The caller must ensure that the given `Text` outlives the `Regex` instance. - pub unsafe fn set_text(&mut self, text: &Text, offset: usize) { + pub unsafe fn set_text(&mut self, text: &mut Text, offset: usize) { + // Get `utext_access_impl` to detect the `TextBuffer::generation` change, + // and refresh its contents. This ensures that ICU doesn't reuse + // stale `UText::chunk_contents`, as it has no way tell that it's stale. + utext_access(text.0, offset as i64, true); + let f = assume_loaded(); let mut status = icu_ffi::U_ZERO_ERROR; unsafe { (f.uregex_setUText)(self.0, text.0 as *const _ as *mut _, &mut status) };