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