diff --git a/src/uu/truncate/src/truncate.rs b/src/uu/truncate/src/truncate.rs index 4b81900c0..df42d7f66 100644 --- a/src/uu/truncate/src/truncate.rs +++ b/src/uu/truncate/src/truncate.rs @@ -202,6 +202,9 @@ fn truncate_reference_and_size( } Ok(m) => m, }; + if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode { + return Err(USimpleError::new(1, "division by zero")); + } let metadata = metadata(rfilename).map_err(|e| match e.kind() { ErrorKind::NotFound => USimpleError::new( 1, @@ -271,6 +274,9 @@ fn truncate_reference_file_only( fn truncate_size_only(size_string: &str, filenames: Vec, create: bool) -> UResult<()> { let mode = parse_mode_and_size(size_string) .map_err(|e| USimpleError::new(1, format!("Invalid number: {}", e)))?; + if let TruncateMode::RoundDown(0) | TruncateMode::RoundUp(0) = mode { + return Err(USimpleError::new(1, "division by zero")); + } for filename in &filenames { let fsize = match metadata(filename) { Ok(m) => m.len(), diff --git a/tests/by-util/test_truncate.rs b/tests/by-util/test_truncate.rs index bb76e8b94..135c55456 100644 --- a/tests/by-util/test_truncate.rs +++ b/tests/by-util/test_truncate.rs @@ -346,3 +346,34 @@ fn test_new_file_no_create() { .no_stderr(); assert!(!at.file_exists(filename)); } + +#[test] +fn test_division_by_zero_size_only() { + new_ucmd!() + .args(&["-s", "/0", "file"]) + .fails() + .no_stdout() + .stderr_contains("division by zero"); + new_ucmd!() + .args(&["-s", "%0", "file"]) + .fails() + .no_stdout() + .stderr_contains("division by zero"); +} + +#[test] +fn test_division_by_zero_reference_and_size() { + let (at, mut ucmd) = at_and_ucmd!(); + at.make_file(FILE1); + ucmd.args(&["-r", FILE1, "-s", "/0", "file"]) + .fails() + .no_stdout() + .stderr_contains("division by zero"); + + let (at, mut ucmd) = at_and_ucmd!(); + at.make_file(FILE1); + ucmd.args(&["-r", FILE1, "-s", "%0", "file"]) + .fails() + .no_stdout() + .stderr_contains("division by zero"); +}