Avoid INT_MIN % -1 and INT_MIN / -1
Those throw arithmetic exceptions as the result doesn't fit into an integer. Fixes: QTBUG-75030 Change-Id: Ibd978848f42cf1c9da1e4af2dc9d7da123ef8f5a Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
parent
651177db69
commit
7878701165
|
@ -1942,6 +1942,7 @@ ReturnedValue Runtime::method_div(const Value &left, const Value &right)
|
||||||
int lval = left.integerValue();
|
int lval = left.integerValue();
|
||||||
int rval = right.integerValue();
|
int rval = right.integerValue();
|
||||||
if (rval != 0 // division by zero should result in a NaN
|
if (rval != 0 // division by zero should result in a NaN
|
||||||
|
&& !(lval == std::numeric_limits<int>::min() && rval == -1) // doesn't fit in int
|
||||||
&& (lval % rval == 0) // fractions can't be stored in an int
|
&& (lval % rval == 0) // fractions can't be stored in an int
|
||||||
&& !(lval == 0 && rval < 0)) // 0 / -something results in -0.0
|
&& !(lval == 0 && rval < 0)) // 0 / -something results in -0.0
|
||||||
return Encode(int(lval / rval));
|
return Encode(int(lval / rval));
|
||||||
|
|
|
@ -366,6 +366,7 @@ private slots:
|
||||||
void tailCallWithArguments();
|
void tailCallWithArguments();
|
||||||
void deleteSparseInIteration();
|
void deleteSparseInIteration();
|
||||||
void saveAccumulatorBeforeToInt32();
|
void saveAccumulatorBeforeToInt32();
|
||||||
|
void intMinDividedByMinusOne();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
|
// static void propertyVarWeakRefCallback(v8::Persistent<v8::Value> object, void* parameter);
|
||||||
|
@ -8941,6 +8942,22 @@ void tst_qqmlecmascript::saveAccumulatorBeforeToInt32()
|
||||||
QCOMPARE(value.toString(), QLatin1String("RangeError: Maximum call stack size exceeded."));
|
QCOMPARE(value.toString(), QLatin1String("RangeError: Maximum call stack size exceeded."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void tst_qqmlecmascript::intMinDividedByMinusOne()
|
||||||
|
{
|
||||||
|
QQmlEngine engine;
|
||||||
|
QQmlComponent component(&engine);
|
||||||
|
component.setData(QByteArray("import QtQml 2.2\n"
|
||||||
|
"QtObject {\n"
|
||||||
|
" property int intMin: -2147483648\n"
|
||||||
|
" property int minusOne: -1\n"
|
||||||
|
" property double doesNotFitInInt: intMin / minusOne\n"
|
||||||
|
"}"), QUrl());
|
||||||
|
QVERIFY(component.isReady());
|
||||||
|
QScopedPointer<QObject> object(component.create());
|
||||||
|
QVERIFY(!object.isNull());
|
||||||
|
QCOMPARE(object->property("doesNotFitInInt").toUInt(), 2147483648u);
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_MAIN(tst_qqmlecmascript)
|
QTEST_MAIN(tst_qqmlecmascript)
|
||||||
|
|
||||||
#include "tst_qqmlecmascript.moc"
|
#include "tst_qqmlecmascript.moc"
|
||||||
|
|
Loading…
Reference in New Issue