diff --git a/src/uu/split/src/split.rs b/src/uu/split/src/split.rs index 227508b7810..bf97017e32c 100644 --- a/src/uu/split/src/split.rs +++ b/src/uu/split/src/split.rs @@ -1137,7 +1137,9 @@ fn n_chunks_by_line( let num_line_bytes = bytes.len() as u64; num_bytes_written += num_line_bytes; let mut skipped = -1; - while num_bytes_should_be_written <= num_bytes_written { + // Stop at the last chunk: with more chunks than bytes the increment is 0, + // so without this bound the loop spins until chunk_number/skipped overflow. + while num_bytes_should_be_written <= num_bytes_written && chunk_number < num_chunks { num_bytes_should_be_written += chunk_size_base + (chunk_size_reminder > chunk_number) as u64; chunk_number += 1; diff --git a/tests/by-util/test_split.rs b/tests/by-util/test_split.rs index bb76dceb31f..95a8bd21630 100644 --- a/tests/by-util/test_split.rs +++ b/tests/by-util/test_split.rs @@ -253,6 +253,19 @@ fn test_split_num_prefixed_chunks_by_lines() { assert_eq!(glob.collate(), at.read_bytes(name)); } +#[test] +fn test_number_of_chunks_by_line_more_chunks_than_bytes() { + // More chunks than bytes must not overflow; the trailing chunks are empty. + let (at, mut ucmd) = at_and_ucmd!(); + at.write("in", "ab"); + ucmd.args(&["-n", "l/5", "in"]).succeeds().no_stderr(); + assert_eq!(at.read("xaa"), "ab"); + for name in ["xab", "xac", "xad", "xae"] { + assert_eq!(at.read(name), ""); + } + assert!(!at.file_exists("xaf")); +} + #[test] fn test_split_str_prefixed_chunks_by_lines() { let (at, mut ucmd) = at_and_ucmd!();