Skip to content

Commit 5eadcbb

Browse files
committed
guard negative operands in MathLib::value shift operators
1 parent 22b3464 commit 5eadcbb

2 files changed

Lines changed: 17 additions & 2 deletions

File tree

lib/mathlib.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ MathLib::value MathLib::value::shiftLeft(const MathLib::value &v) const
266266
if (!isInt() || !v.isInt())
267267
throw InternalError(nullptr, "Shift operand is not integer");
268268
MathLib::value ret(*this);
269-
if (v.mIntValue >= MathLib::bigint_bits) {
269+
if (v.mIntValue < 0 || v.mIntValue >= MathLib::bigint_bits || ret.mIntValue < 0) {
270270
return ret;
271271
}
272272
ret.mIntValue <<= v.mIntValue;
@@ -278,7 +278,7 @@ MathLib::value MathLib::value::shiftRight(const MathLib::value &v) const
278278
if (!isInt() || !v.isInt())
279279
throw InternalError(nullptr, "Shift operand is not integer");
280280
MathLib::value ret(*this);
281-
if (v.mIntValue >= MathLib::bigint_bits) {
281+
if (v.mIntValue < 0 || v.mIntValue >= MathLib::bigint_bits) {
282282
return ret;
283283
}
284284
ret.mIntValue >>= v.mIntValue;

test/testmathlib.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ class TestMathLib : public TestFixture {
6464
TEST_CASE(tan);
6565
TEST_CASE(abs);
6666
TEST_CASE(toString);
67+
TEST_CASE(valueShift);
6768
}
6869

6970
void isGreater() const {
@@ -1511,6 +1512,20 @@ class TestMathLib : public TestFixture {
15111512
ASSERT_EQUALS("2.22507385851e-308", MathLib::toString(std::numeric_limits<double>::min()));
15121513
ASSERT_EQUALS("1.79769313486e+308", MathLib::toString(std::numeric_limits<double>::max()));
15131514
}
1515+
1516+
void valueShift() const {
1517+
// ordinary shifts
1518+
ASSERT_EQUALS("16", (MathLib::value("1") << MathLib::value("4")).str());
1519+
ASSERT_EQUALS("64", (MathLib::value("256") >> MathLib::value("2")).str());
1520+
1521+
// a large hex literal is not negative as a string but parses to a negative
1522+
// bigint; shifting it must not be performed (left shift of a negative value
1523+
// and shifting by a negative count are both undefined). the operand is
1524+
// returned unchanged, as already done for counts >= bigint_bits.
1525+
ASSERT_EQUALS("9223372036854775808U", (MathLib::value("0x8000000000000000") << MathLib::value("1")).str());
1526+
ASSERT_EQUALS("1", (MathLib::value("1") << MathLib::value("0x8000000000000000")).str());
1527+
ASSERT_EQUALS("1", (MathLib::value("1") >> MathLib::value("0x8000000000000000")).str());
1528+
}
15141529
};
15151530

15161531
REGISTER_TEST(TestMathLib)

0 commit comments

Comments
 (0)