diff --git a/crates/bashkit/src/interpreter/mod.rs b/crates/bashkit/src/interpreter/mod.rs index e0df17d67..dafe21f40 100644 --- a/crates/bashkit/src/interpreter/mod.rs +++ b/crates/bashkit/src/interpreter/mod.rs @@ -11112,22 +11112,24 @@ impl Interpreter { } let mut results = Vec::new(); - // Bash behavior: direction is determined by start/end, - // step sign determines actual increment direction + // Bash behavior: direction is determined by start/end. Keep stepping in i128 so + // huge but valid i64 steps cannot overflow after the precomputed range cap passes. + let step_magnitude = step.unsigned_abs() as i128; let effective_step = if start_num <= end_num { - step.abs() + step_magnitude } else { - -(step.abs()) + -step_magnitude }; - let mut i = start_num; + let mut i = start_num as i128; + let end = end_num as i128; if effective_step > 0 { - while i <= end_num { + while i <= end { results.push(i.to_string()); i += effective_step; } } else { - while i >= end_num { + while i >= end { results.push(i.to_string()); i += effective_step; } @@ -11233,6 +11235,24 @@ mod tests { ); } + #[test] + fn test_try_expand_range_numeric_large_step_does_not_overflow() { + let fs: Arc = Arc::new(InMemoryFs::new()); + let interp = Interpreter::new(Arc::clone(&fs)); + + assert_eq!( + interp + .try_expand_range("9223372036854775802..9223372036854775807..9223372036854775807"), + Some(vec!["9223372036854775802".to_string()]) + ); + assert_eq!( + interp.try_expand_range( + "-9223372036854775803..-9223372036854775808..-9223372036854775808" + ), + Some(vec!["-9223372036854775803".to_string()]) + ); + } + /// Test timeout with paused time for deterministic behavior #[tokio::test(start_paused = true)] async fn test_timeout_expires_deterministically() {