mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 07:14:28 +00:00
Fix panic on string slicing error to truncate the string
The string may be arbitrarily long, but we want to limit the panic message to a reasonable length. Truncate the string if it is too long (simply to char boundary). Also add details to the start <= end message. I think it's ok to flesh out the code here, since it's in a cold function.
This commit is contained in:
parent
c97524bef9
commit
4594f0f67a
@ -346,6 +346,26 @@ fn test_slice_fail() {
|
||||
&"中华Việt Nam"[0..2];
|
||||
}
|
||||
|
||||
const LOREM_PARAGRAPH: &'static str = "\
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse quis lorem sit amet dolor \
|
||||
ultricies condimentum. Praesent iaculis purus elit, ac malesuada quam malesuada in. Duis sed orci \
|
||||
eros. Suspendisse sit amet magna mollis, mollis nunc luctus, imperdiet mi. Integer fringilla non \
|
||||
sem ut lacinia. Fusce varius tortor a risus porttitor hendrerit. Morbi mauris dui, ultricies nec \
|
||||
tempus vel, gravida nec quam.";
|
||||
|
||||
// check the panic includes the prefix of the sliced string
|
||||
#[test]
|
||||
#[should_panic(expected="Lorem ipsum dolor sit amet")]
|
||||
fn test_slice_fail_truncated_1() {
|
||||
&LOREM_PARAGRAPH[..1024];
|
||||
}
|
||||
// check the truncation in the panic message
|
||||
#[test]
|
||||
#[should_panic(expected="luctus, im`[...] do not lie on character boundary")]
|
||||
fn test_slice_fail_truncated_2() {
|
||||
&LOREM_PARAGRAPH[..1024];
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_slice_from() {
|
||||
assert_eq!(&"abcd"[0..], "abcd");
|
||||
|
@ -1591,12 +1591,30 @@ pub trait StrExt {
|
||||
fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
|
||||
}
|
||||
|
||||
// truncate `&str` to length at most equal to `max`
|
||||
// return `true` if it were truncated, and the new str.
|
||||
fn truncate_to_char_boundary(s: &str, mut max: usize) -> (bool, &str) {
|
||||
if max >= s.len() {
|
||||
(false, s)
|
||||
} else {
|
||||
while !s.is_char_boundary(max) {
|
||||
max -= 1;
|
||||
}
|
||||
(true, &s[..max])
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(never)]
|
||||
#[cold]
|
||||
fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
|
||||
assert!(begin <= end);
|
||||
panic!("index {} and/or {} in `{}` do not lie on character boundary",
|
||||
begin, end, s);
|
||||
const MAX_DISPLAY_LENGTH: usize = 256;
|
||||
let (truncated, s) = truncate_to_char_boundary(s, MAX_DISPLAY_LENGTH);
|
||||
let ellipsis = if truncated { "[...]" } else { "" };
|
||||
|
||||
assert!(begin <= end, "begin <= end ({} <= {}) when slicing `{}`{}",
|
||||
begin, end, s, ellipsis);
|
||||
panic!("index {} and/or {} in `{}`{} do not lie on character boundary",
|
||||
begin, end, s, ellipsis);
|
||||
}
|
||||
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
|
Loading…
Reference in New Issue
Block a user