1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

sleep: Fix duration parsing of multiple inputs when duration overflow should saturate and not panic

This commit is contained in:
Joining7943 2023-02-26 07:32:07 +01:00
parent 5e851d4bde
commit 68f75af678
2 changed files with 47 additions and 21 deletions

View file

@ -69,7 +69,7 @@ fn sleep(args: &[&str]) -> UResult<()> {
Duration::new(0, 0) Duration::new(0, 0)
} }
}); });
let sleep_dur = intervals.fold(Duration::new(0, 0), |acc, n| acc + n); let sleep_dur = intervals.fold(Duration::ZERO, |acc, n| acc.saturating_add(n));
if arg_error { if arg_error {
return Err(UUsageError::new(1, "")); return Err(UUsageError::new(1, ""));
}; };

View file

@ -129,29 +129,55 @@ fn test_sleep_wrong_time() {
new_ucmd!().args(&["0.1s", "abc"]).fails(); new_ucmd!().args(&["0.1s", "abc"]).fails();
} }
// TODO These tests would obviously block for a very long time. We #[test]
// only want to verify that there is no error here, so we could just fn test_sleep_when_single_input_exceeds_max_duration_then_no_error() {
// figure out a way to terminate the child process after a short let mut child = new_ucmd!()
// period of time. .arg(format!("{}", u64::MAX as u128 + 1))
.timeout(Duration::from_secs(10))
.run_no_wait();
// #[test] #[cfg(unix)]
#[allow(dead_code)] child
fn test_dont_overflow() { .delay(100)
new_ucmd!() .kill()
.arg("9223372036854775808d") .make_assertion()
.succeeds() .with_current_output()
.no_stderr() .signal_is(9) // make sure it was us who terminated the process
.no_stdout(); .no_output();
#[cfg(windows)]
child
.delay(100)
.kill()
.make_assertion()
.with_current_output()
.failure()
.no_output();
} }
// #[test] #[test]
#[allow(dead_code)] fn test_sleep_when_multiple_inputs_exceed_max_duration_then_no_error() {
fn test_sum_overflow() { let mut child = new_ucmd!()
new_ucmd!() .arg(format!("{}", u64::MAX))
.args(&["100000000000000d", "100000000000000d", "100000000000000d"]) .arg("1")
.succeeds() .timeout(Duration::from_secs(10))
.no_stderr() .run_no_wait();
.no_stdout();
#[cfg(unix)]
child
.delay(100)
.kill()
.make_assertion()
.with_current_output()
.signal_is(9) // make sure it was us who terminated the process
.no_output();
#[cfg(windows)]
child
.delay(100)
.kill()
.make_assertion()
.with_current_output()
.failure()
.no_output();
} }
#[test] #[test]