@@ -60,44 +60,45 @@ struct Config {
6060/// Parse a duration string with overflow protection
6161/// Caps extremely large values at a safe maximum that works on all platforms
6262fn parse_duration_with_overflow_protection ( duration_str : & str ) -> UResult < Duration > {
63- // Find where the unit suffix starts (first non-digit character)
63+ // Pre-check for extremely large values that would overflow
64+ // Only intercept if it's a simple integer + unit suffix pattern
6465 let numeric_end = duration_str
6566 . find ( |c : char | !c. is_ascii_digit ( ) )
6667 . unwrap_or ( duration_str. len ( ) ) ;
67- let numeric_part = & duration_str[ ..numeric_end] ;
68- let unit_suffix = & duration_str[ numeric_end..] ;
69-
70- if let Ok ( num) = numeric_part. parse :: < u128 > ( ) {
71- match unit_suffix {
72- "" | "s" | "m" | "h" | "d" => {
73- let ( multiplier, max_safe) = match unit_suffix {
74- "" | "s" => ( 1u64 , u64:: MAX ) ,
75- "m" => ( 60 , u64:: MAX / 60 ) ,
76- "h" => ( 3600 , u64:: MAX / 3600 ) ,
77- "d" => ( 86400 , u64:: MAX / 86400 ) ,
78- _ => unreachable ! ( ) ,
79- } ;
80-
81- if num > max_safe as u128 {
82- // Cap at a safe maximum (~34 years) that works on all platforms
83- // This matches the cap in process.rs for kqueue/sigtimedwait
84- const MAX_SAFE_TIMEOUT_SECS : u64 = ( i32:: MAX / 2 ) as u64 ;
85- Ok ( Duration :: from_secs ( MAX_SAFE_TIMEOUT_SECS ) )
86- } else {
87- let secs = ( num as u64 ) * multiplier;
88- Ok ( Duration :: from_secs ( secs) )
89- }
90- }
91- _ => {
92- // Unknown suffix, fallback to parse_time
93- parse_time:: from_str ( duration_str, true )
94- . map_err ( |err| UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) )
68+
69+ // Only apply overflow protection if we have a simple pattern: all digits followed by optional unit
70+ if numeric_end > 0
71+ && ( numeric_end == duration_str. len ( )
72+ || matches ! (
73+ duration_str. chars( ) . nth( numeric_end) ,
74+ Some ( 's' ) | Some ( 'm' ) | Some ( 'h' ) | Some ( 'd' )
75+ ) )
76+ {
77+ let numeric_part = & duration_str[ ..numeric_end] ;
78+ let unit_suffix = & duration_str[ numeric_end..] ;
79+
80+ if let Ok ( num) = numeric_part. parse :: < u128 > ( ) {
81+ // Check if this would cause overflow
82+ let ( _multiplier, max_safe) = match unit_suffix {
83+ "" | "s" => ( 1u64 , u64:: MAX ) ,
84+ "m" => ( 60 , u64:: MAX / 60 ) ,
85+ "h" => ( 3600 , u64:: MAX / 3600 ) ,
86+ "d" => ( 86400 , u64:: MAX / 86400 ) ,
87+ _ => ( 1u64 , u64:: MAX ) , // Shouldn't reach here
88+ } ;
89+
90+ if num > max_safe as u128 {
91+ // Cap at a safe maximum (~34 years) that works on all platforms
92+ // This matches the cap in process.rs for kqueue/sigtimedwait
93+ const MAX_SAFE_TIMEOUT_SECS : u64 = ( i32:: MAX / 2 ) as u64 ;
94+ return Ok ( Duration :: from_secs ( MAX_SAFE_TIMEOUT_SECS ) ) ;
9595 }
9696 }
97- } else {
98- parse_time:: from_str ( duration_str, true )
99- . map_err ( |err| UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) )
10097 }
98+
99+ // For all other cases (including normal values), use the standard parser
100+ parse_time:: from_str ( duration_str, true )
101+ . map_err ( |err| UUsageError :: new ( ExitStatus :: TimeoutFailed . into ( ) , err) )
101102}
102103
103104impl Config {
0 commit comments