Skip to content

Commit 57a5ee9

Browse files
committed
Auto merge of #152998 - xtqqczze:panic-truncate, r=jhpratt
std: make `OsString::truncate` a no-op when `len > current_len` Align `OsString::truncate` (and the underlying WTF-8 implementation) with `String::truncate` by making it a no-op when `len > self.len()`. Previously, `OsString::truncate` would panic if `len > self.len()`, while `String::truncate` treats such cases as a no-op. Tracking (`os_string_truncate`): #133262 See also: #32977 cc: @alexcrichton, @lolbinarycat
2 parents b711f95 + 3ecd18c commit 57a5ee9

3 files changed

Lines changed: 19 additions & 9 deletions

File tree

library/alloc/src/wtf8/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -342,14 +342,18 @@ impl Wtf8Buf {
342342

343343
/// Shortens a string to the specified length.
344344
///
345+
/// If `new_len` is greater than the string's current length, this has no
346+
/// effect.
347+
///
345348
/// # Panics
346349
///
347-
/// Panics if `new_len` > current length,
348-
/// or if `new_len` is not a code point boundary.
350+
/// Panics if `new_len` does not lie on a code point boundary.
349351
#[inline]
350352
pub fn truncate(&mut self, new_len: usize) {
351-
assert!(self.is_code_point_boundary(new_len));
352-
self.bytes.truncate(new_len)
353+
if new_len <= self.len() {
354+
assert!(self.is_code_point_boundary(new_len));
355+
self.bytes.truncate(new_len)
356+
}
353357
}
354358

355359
/// Consumes the WTF-8 string and tries to convert it to a vec of bytes.

library/alloc/src/wtf8/tests.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,10 +308,10 @@ fn wtf8buf_truncate_fail_code_point_boundary() {
308308
}
309309

310310
#[test]
311-
#[should_panic]
312-
fn wtf8buf_truncate_fail_longer() {
311+
fn wtf8buf_truncate_invalid_len() {
313312
let mut string = Wtf8Buf::from_str("aé");
314313
string.truncate(4);
314+
assert_eq!(string, Wtf8Buf::from_str("aé"));
315315
}
316316

317317
#[test]

library/std/src/ffi/os_str.rs

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -576,15 +576,21 @@ impl OsString {
576576

577577
/// Truncate the `OsString` to the specified length.
578578
///
579+
/// If `new_len` is greater than the string's current length, this has no
580+
/// effect.
581+
///
579582
/// # Panics
583+
///
580584
/// Panics if `len` does not lie on a valid `OsStr` boundary
581585
/// (as described in [`OsStr::slice_encoded_bytes`]).
582586
#[inline]
583587
#[unstable(feature = "os_string_truncate", issue = "133262")]
584588
pub fn truncate(&mut self, len: usize) {
585-
self.as_os_str().inner.check_public_boundary(len);
586-
// SAFETY: The length was just checked to be at a valid boundary.
587-
unsafe { self.inner.truncate_unchecked(len) };
589+
if len <= self.len() {
590+
self.as_os_str().inner.check_public_boundary(len);
591+
// SAFETY: The length was just checked to be at a valid boundary.
592+
unsafe { self.inner.truncate_unchecked(len) };
593+
}
588594
}
589595

590596
/// Provides plumbing to `Vec::extend_from_slice` without giving full

0 commit comments

Comments
 (0)