Skip to content

Commit eb5d0e0

Browse files
committed
fix: overflow panic when shifting left value greater then 31
1 parent aadd2c1 commit eb5d0e0

File tree

2 files changed

+23
-3
lines changed
  • crates/rspack_plugin_javascript/src/utils/eval
  • packages/rspack-test-tools/tests/normalCases/parsing/evaluate-if-binary

2 files changed

+23
-3
lines changed

crates/rspack_plugin_javascript/src/utils/eval/eval_binary_expr.rs

+21-3
Original file line numberDiff line numberDiff line change
@@ -429,16 +429,34 @@ pub fn handle_const_operation(
429429
None
430430
}
431431
}
432-
BinaryOp::BitAnd | BinaryOp::BitXor | BinaryOp::BitOr | BinaryOp::LShift | BinaryOp::RShift => {
432+
BinaryOp::LShift | BinaryOp::RShift => {
433+
if let Some(left_number) = left.as_int()
434+
&& let Some(right_number) = right.as_int()
435+
{
436+
// only the lower 5 bits are used when shifting, so don't do anything
437+
// if the shift amount is outside [0,32)
438+
if (0..32).contains(&right_number) {
439+
res.set_number(match expr.op {
440+
BinaryOp::LShift => left_number << right_number,
441+
BinaryOp::RShift => left_number >> right_number,
442+
_ => unreachable!(),
443+
} as f64);
444+
} else {
445+
res.set_number(left_number as f64);
446+
}
447+
Some(res)
448+
} else {
449+
None
450+
}
451+
}
452+
BinaryOp::BitAnd | BinaryOp::BitXor | BinaryOp::BitOr => {
433453
if let Some(left_number) = left.as_int()
434454
&& let Some(right_number) = right.as_int()
435455
{
436456
res.set_number(match expr.op {
437457
BinaryOp::BitAnd => left_number & right_number,
438458
BinaryOp::BitXor => left_number ^ right_number,
439459
BinaryOp::BitOr => left_number | right_number,
440-
BinaryOp::LShift => left_number << right_number,
441-
BinaryOp::RShift => left_number >> right_number,
442460
_ => unreachable!(),
443461
} as f64);
444462
Some(res)

packages/rspack-test-tools/tests/normalCases/parsing/evaluate-if-binary/index.js

+2
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ it("should handle bit operation", () => {
1818
if ((1 ^ 2) !== 3) require("fail");
1919
if ((1 << 1) !== 2) require("fail");
2020
if ((2 >> 1) !== 1) require("fail");
21+
if ((2 >> 32) !== 2) require("fail");
22+
if ((2 << 32) !== 2) require("fail");
2123
});
2224

2325
it("should handle number operation", () => {

0 commit comments

Comments
 (0)