fix: slicing at an offset that is not char boundary (#188)

This commit is contained in:
Myriad-Dreamin 2024-04-15 00:46:10 +08:00 committed by GitHub
parent 882dd6ad27
commit f98470a0f5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 38 additions and 2 deletions

View file

@ -995,8 +995,11 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
/// A small window of context before the cursor.
fn before_window(&self, size: usize) -> &str {
// todo: bad slicing
&self.before[self.cursor.saturating_sub(size)..]
safe_str_slice(
self.before,
self.cursor.saturating_sub(size),
self.before.len(),
)
}
/// Add a prefix and suffix to all applications.
@ -1265,3 +1268,20 @@ impl<'a, 'w> CompletionContext<'a, 'w> {
}
}
}
fn safe_str_slice(s: &str, mut start: usize, mut end: usize) -> &str {
// todo: bad slicing
// &self.before[self.cursor.saturating_sub(size)..]
while start < s.len() && !s.is_char_boundary(start) {
start += 1;
}
while end > 0 && !s.is_char_boundary(end) {
end -= 1;
}
if end >= start {
&s[start..end]
} else {
""
}
}

View file

@ -814,3 +814,19 @@ pub fn complete_path(
.collect_vec(),
)
}
#[cfg(test)]
mod tests {
use crate::upstream::complete::safe_str_slice;
#[test]
fn test_before() {
const TEST_UTF8_STR: &str = "我们";
for i in 0..=TEST_UTF8_STR.len() {
for j in 0..=TEST_UTF8_STR.len() {
let _s = std::hint::black_box(safe_str_slice(TEST_UTF8_STR, i, j));
}
}
}
}