From ebe7a7b21a9e46f4b5b10250598fd74a30fcdee9 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Sat, 30 Aug 2025 23:21:47 +0200 Subject: [PATCH 1/2] =?UTF-8?q?fix:=C2=A0Panic=20in=20unicode=20boundary?= =?UTF-8?q?=20checking=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since the full length of the string is a valid unicode boundary, the range of lengths to check needs to end with the "len + 1" excluded upper bound. --- src/std_ext.rs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/std_ext.rs b/src/std_ext.rs index 24949c3..41a78c4 100644 --- a/src/std_ext.rs +++ b/src/std_ext.rs @@ -34,9 +34,25 @@ impl StrExt for &'_ str { if index > len { len } else { - (index..len) + (index..(len + 1)) .find(|&i| self.is_char_boundary(i)) .expect("`i = len` must be a char boundary") // otherwise `self` wouldn't have been a valid `&str` to begin with } } } + +#[cfg(test)] +mod test { + use crate::StrExt; + + #[allow(unstable_name_collisions)] + #[test] + fn char_boundary_at_end() { + let string = "❤️🧡💛"; + assert_eq!(string.ceil_char_boundary(0), 0); + assert_eq!(string.ceil_char_boundary(1), 3); + assert_eq!(string.ceil_char_boundary(3), 3); + assert_eq!(string.ceil_char_boundary(4), 6); + assert_eq!(string.ceil_char_boundary(13), string.len()); + } +} -- 2.47.3 From dfb6c5a2d2e14e6ea1641143da8746a24b2c404f Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Sun, 31 Aug 2025 09:03:03 +0200 Subject: [PATCH 2/2] Integrate review feedback --- src/std_ext.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/std_ext.rs b/src/std_ext.rs index 41a78c4..8b9c906 100644 --- a/src/std_ext.rs +++ b/src/std_ext.rs @@ -34,7 +34,7 @@ impl StrExt for &'_ str { if index > len { len } else { - (index..(len + 1)) + (index..=len) .find(|&i| self.is_char_boundary(i)) .expect("`i = len` must be a char boundary") // otherwise `self` wouldn't have been a valid `&str` to begin with } @@ -43,7 +43,7 @@ impl StrExt for &'_ str { #[cfg(test)] mod test { - use crate::StrExt; + use super::*; #[allow(unstable_name_collisions)] #[test] -- 2.47.3