@@ -63,50 +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- // Try standard parsing first
67- match parse_time:: from_str ( duration_str, true ) {
68- Ok ( duration) => Ok ( duration) ,
69- Err ( _) => {
70- // If parsing fails, check if it's due to overflow with huge values
71- // Only try to handle simple numeric patterns: digits + optional unit suffix
72- let numeric_end = duration_str
73- . find ( |c : char | !c. is_ascii_digit ( ) )
74- . unwrap_or ( duration_str. len ( ) ) ;
75-
76- if numeric_end > 0 {
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 looks like a huge value that would overflow
82- let max_safe = match unit_suffix {
83- "" | "s" => u64:: MAX ,
84- "m" => u64:: MAX / 60 ,
85- "h" => u64:: MAX / 3600 ,
86- "d" => u64:: MAX / 86400 ,
87- _ => {
88- return Err ( UUsageError :: new (
89- ExitStatus :: TimeoutFailed . into ( ) ,
90- format ! ( "invalid time interval {duration_str}" ) ,
91- ) ) ;
92- }
93- } ;
94-
95- if num > max_safe as u128 {
96- // Cap at a safe maximum (~34 years) that works on all platforms
97- const MAX_SAFE_TIMEOUT_SECS : u64 = ( i32:: MAX / 2 ) as u64 ;
98- return Ok ( Duration :: from_secs ( MAX_SAFE_TIMEOUT_SECS ) ) ;
99- }
100- }
101- }
102-
103- // If it wasn't an overflow case, return the original error
104- Err ( UUsageError :: new (
105- ExitStatus :: TimeoutFailed . into ( ) ,
106- format ! ( "invalid time interval {duration_str}" ) ,
66+ // Pre-check for extremely large values that would overflow
67+ // Only intercept if it's a simple integer + unit suffix pattern
68+ let numeric_end = duration_str
69+ . find ( |c : char | !c. is_ascii_digit ( ) )
70+ . unwrap_or ( duration_str. len ( ) ) ;
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' )
10778 ) )
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 ) ) ;
98+ }
10899 }
109100 }
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) )
110105}
111106
112107impl Config {
0 commit comments