Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
78 changes: 69 additions & 9 deletions crates/bashkit/src/interpreter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7340,7 +7340,9 @@ impl Interpreter {
{
let left = self.parse_arithmetic_impl(&expr[..i - 1], arith_depth + 1);
let right = self.parse_arithmetic_impl(&expr[i + 1..], arith_depth + 1);
return left << right;
// THREAT[TM-DOS-029]: clamp shift to 0..=63 to prevent panic
let shift = right.clamp(0, 63) as u32;
return left.wrapping_shl(shift);
}
'>' if depth == 0
&& i > 0
Expand All @@ -7350,7 +7352,9 @@ impl Interpreter {
{
let left = self.parse_arithmetic_impl(&expr[..i - 1], arith_depth + 1);
let right = self.parse_arithmetic_impl(&expr[i + 1..], arith_depth + 1);
return left >> right;
// THREAT[TM-DOS-029]: clamp shift to 0..=63 to prevent panic
let shift = right.clamp(0, 63) as u32;
return left.wrapping_shr(shift);
}
_ => {}
}
Expand Down Expand Up @@ -7378,10 +7382,11 @@ impl Interpreter {
}
let left = self.parse_arithmetic_impl(&expr[..i], arith_depth + 1);
let right = self.parse_arithmetic_impl(&expr[i + 1..], arith_depth + 1);
// THREAT[TM-DOS-029]: wrapping to prevent overflow panic
return if chars[i] == '+' {
left + right
left.wrapping_add(right)
} else {
left - right
left.wrapping_sub(right)
};
}
_ => {}
Expand All @@ -7404,22 +7409,24 @@ impl Interpreter {
}
let left = self.parse_arithmetic_impl(&expr[..i], arith_depth + 1);
let right = self.parse_arithmetic_impl(&expr[i + 1..], arith_depth + 1);
return left * right;
// THREAT[TM-DOS-029]: wrapping to prevent overflow panic
return left.wrapping_mul(right);
}
'/' | '%' if depth == 0 => {
let left = self.parse_arithmetic_impl(&expr[..i], arith_depth + 1);
let right = self.parse_arithmetic_impl(&expr[i + 1..], arith_depth + 1);
// THREAT[TM-DOS-029]: wrapping to prevent i64::MIN / -1 panic
return match chars[i] {
'/' => {
if right != 0 {
left / right
left.wrapping_div(right)
} else {
0
}
}
'%' => {
if right != 0 {
left % right
left.wrapping_rem(right)
} else {
0
}
Expand All @@ -7441,7 +7448,9 @@ impl Interpreter {
let left = self.parse_arithmetic_impl(&expr[..i], arith_depth + 1);
// Right-associative: parse from i+2 onward (may contain more **)
let right = self.parse_arithmetic_impl(&expr[i + 2..], arith_depth + 1);
return left.pow(right as u32);
// THREAT[TM-DOS-029]: clamp exponent to 0..=63 to prevent panic/hang
let exp = right.clamp(0, 63) as u32;
return left.wrapping_pow(exp);
}
_ => {}
}
Expand All @@ -7451,7 +7460,10 @@ impl Interpreter {
if let Some(rest) = expr.strip_prefix('-') {
let rest = rest.trim();
if !rest.is_empty() {
return -self.parse_arithmetic_impl(rest, arith_depth + 1);
// THREAT[TM-DOS-029]: wrapping to prevent i64::MIN negation panic
return self
.parse_arithmetic_impl(rest, arith_depth + 1)
.wrapping_neg();
}
}
if let Some(rest) = expr.strip_prefix('~') {
Expand Down Expand Up @@ -9314,4 +9326,52 @@ mod tests {
let result = run_script("set a b c\necho $#\necho $1 $2 $3").await;
assert_eq!(result.stdout, "3\na b c\n");
}

#[tokio::test]
async fn test_arithmetic_exponent_negative_no_panic() {
let result = run_script("echo $(( 2 ** -1 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_exponent_large_no_panic() {
let result = run_script("echo $(( 2 ** 100 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_shift_large_no_panic() {
let result = run_script("echo $(( 1 << 64 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_shift_negative_no_panic() {
let result = run_script("echo $(( 1 << -1 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_div_min_neg1_no_panic() {
let result = run_script("echo $(( -9223372036854775808 / -1 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_mod_min_neg1_no_panic() {
let result = run_script("echo $(( -9223372036854775808 % -1 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_overflow_add_no_panic() {
let result = run_script("echo $(( 9223372036854775807 + 1 ))").await;
assert_eq!(result.exit_code, 0);
}

#[tokio::test]
async fn test_arithmetic_overflow_mul_no_panic() {
let result = run_script("echo $(( 9223372036854775807 * 2 ))").await;
assert_eq!(result.exit_code, 0);
}
}
Loading