Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/uu/ptx/src/ptx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -457,11 +457,11 @@ fn get_output_chunks(
// https://github.com/MaiZure/coreutils-8.3/blob/master/src/ptx.c#L1234
let half_line_size = config.line_width / 2;
let max_before_size = cmp::max(half_line_size as isize - config.gap_size as isize, 0) as usize;

let keyword_len = keyword.chars().count();
let trunc_len = config.trunc_str.chars().count();
let max_after_size = cmp::max(
half_line_size as isize
- (2 * config.trunc_str.len()) as isize
- keyword.len() as isize
- 1,
half_line_size as isize - (2 * trunc_len) as isize - keyword_len as isize - 1,
0,
) as usize;

Expand Down Expand Up @@ -502,7 +502,7 @@ fn get_output_chunks(
// and get the string
let after_str: String = all_after[0..after_end].iter().collect();
after.push_str(&after_str);
assert!(max_after_size >= after.len());
assert!(max_after_size >= after.chars().count());

// the tail chunk

Expand Down
12 changes: 12 additions & 0 deletions tests/by-util/test_ptx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,18 @@ fn test_unicode_truncation_alignment() {
.stdout_only(" / bar\n föö/\n");
}

#[test]
fn test_unicode_in_after_chunk_does_not_panic() {
// Regression test for a panic in get_output_chunks() when the computed
// max_after_size used byte lengths but the output was assembled as chars.
// The emoji is multibyte in UTF-8 and previously could trigger:
// `assertion failed: max_after_size >= after.len()`.
new_ucmd!()
.pipe_in("We've got +11 more G of 1.70. 🛠\n")
.succeeds()
.stdout_contains("We've got +11");
}

#[test]
fn test_duplicate_input_files() {
new_ucmd!()
Expand Down
Loading