@@ -83,22 +83,32 @@ impl Config {
8383 } ,
8484 } ;
8585
86- let duration =
87- match parse_time:: from_str ( options. get_one :: < String > ( options:: DURATION ) . unwrap ( ) , true )
88- {
89- Ok ( d) => d,
90- Err ( err) => {
91- // If parsing fails due to overflow, use maximum valid duration
92- // This handles cases like "9223372036854775808d" (i64::MAX days)
93- let err_str = err. clone ( ) ;
94- if err_str. contains ( "overflow" ) || err_str. contains ( "too large" ) {
95- // Cap at time_t::MAX seconds (maximum valid timeout)
96- Duration :: from_secs ( libc:: time_t:: MAX as u64 )
97- } else {
98- return Err ( UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) ) ;
99- }
86+ // Pre-validate the duration string to avoid overflow in parse_time
87+ // Extract numeric part and check if it's too large before parsing
88+ let duration_str = options. get_one :: < String > ( options:: DURATION ) . unwrap ( ) ;
89+ let duration = {
90+ // Find where the unit suffix starts (first non-digit, non-decimal character)
91+ let numeric_end = duration_str
92+ . find ( |c : char | !c. is_ascii_digit ( ) && c != '.' )
93+ . unwrap_or ( duration_str. len ( ) ) ;
94+ let numeric_part = & duration_str[ ..numeric_end] ;
95+
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 {
102+ Duration :: from_secs ( libc:: time_t:: MAX as u64 )
103+ } else {
104+ parse_time:: from_str ( duration_str, true )
105+ . map_err ( |err| UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) ) ?
100106 }
101- } ;
107+ } else {
108+ parse_time:: from_str ( duration_str, true )
109+ . map_err ( |err| UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) ) ?
110+ }
111+ } ;
102112
103113 let preserve_status: bool = options. get_flag ( options:: PRESERVE_STATUS ) ;
104114 let foreground = options. get_flag ( options:: FOREGROUND ) ;
0 commit comments