Skip to content

Commit 3ca9ba9

Browse files
Replace f64-based overflow check with u128 integer comparison.
1 parent 57dee85 commit 3ca9ba9

File tree

1 file changed

+8
-8
lines changed

1 file changed

+8
-8
lines changed

src/uu/timeout/src/timeout.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,24 +87,24 @@ impl Config {
8787
// Extract numeric part and check if it's too large before parsing
8888
let duration_str = options.get_one::<String>(options::DURATION).unwrap();
8989
let duration = {
90-
// Find where the unit suffix starts (first non-digit, non-decimal character)
90+
// Find where the unit suffix starts (first non-digit character)
9191
let numeric_end = duration_str
92-
.find(|c: char| !c.is_ascii_digit() && c != '.')
92+
.find(|c: char| !c.is_ascii_digit())
9393
.unwrap_or(duration_str.len());
9494
let numeric_part = &duration_str[..numeric_end];
9595

96-
// If the numeric part is huge, cap at maximum valid duration
97-
// i64::MAX seconds is ~292 billion years, i64::MAX days overflows
98-
if let Ok(num) = numeric_part.parse::<f64>() {
99-
// Cap at i64::MAX / 86400 days to prevent overflow in day->second conversion
100-
const MAX_SAFE_DAYS: f64 = (i64::MAX / 86400) as f64;
101-
if num > MAX_SAFE_DAYS {
96+
// Use u128 for robust overflow detection without precision loss
97+
if let Ok(num) = numeric_part.parse::<u128>() {
98+
// Cap at u64::MAX to prevent overflow in any duration conversion
99+
const MAX_SAFE_DURATION_NUM: u128 = u64::MAX as u128;
100+
if num > MAX_SAFE_DURATION_NUM {
102101
Duration::from_secs(libc::time_t::MAX as u64)
103102
} else {
104103
parse_time::from_str(duration_str, true)
105104
.map_err(|err| UUsageError::new(ExitStatus::TimeoutFailed.into(), err))?
106105
}
107106
} else {
107+
// Fallback for non-integer durations like "1.5d"
108108
parse_time::from_str(duration_str, true)
109109
.map_err(|err| UUsageError::new(ExitStatus::TimeoutFailed.into(), err))?
110110
}

0 commit comments

Comments
 (0)