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