QV4String: properly detect overflow when trying to convert to an array index
A wrong overflow detection caused strings like "240000000000" to pass the conversion, even though they would not fit into a uint when converted into base-10. This mis-conversion to uint then caused all sorts of side effects (broken comparisons, wrong listing of properties, and so on). So, properly fix the overflow detection by using our numeric private functions. Change-Id: Icbf67ac68cf5785d6c77b433c7a45aed5285a8c2 Task-number: QTBUG-56830 Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
parent
5861ea797d
commit
64714ea431
|
@ -40,6 +40,7 @@
|
|||
#include "qv4stringobject_p.h"
|
||||
#endif
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/private/qnumeric_p.h>
|
||||
|
||||
using namespace QV4;
|
||||
|
||||
|
@ -57,10 +58,15 @@ static uint toArrayIndex(const QChar *ch, const QChar *end)
|
|||
uint x = ch->unicode() - '0';
|
||||
if (x > 9)
|
||||
return UINT_MAX;
|
||||
uint n = i*10 + x;
|
||||
if (n < i)
|
||||
// overflow
|
||||
|
||||
uint n;
|
||||
// n = i * 10 + x, with overflow checking
|
||||
if (mul_overflow(i, 10u, &n))
|
||||
return UINT_MAX;
|
||||
|
||||
if (add_overflow(n, x, &n))
|
||||
return UINT_MAX;
|
||||
|
||||
i = n;
|
||||
++ch;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
option(host_build)
|
||||
TARGET = QtQmlDevTools
|
||||
QT = core
|
||||
QT = core core-private
|
||||
CONFIG += static internal_module qmldevtools_build
|
||||
|
||||
# Don't use pch because the auto-generated header refers to QtBootstrap,
|
||||
|
|
|
@ -1371,6 +1371,33 @@ void tst_QJSValue::hasProperty_changePrototype()
|
|||
QVERIFY(obj.hasOwnProperty("foo"));
|
||||
}
|
||||
|
||||
void tst_QJSValue::hasProperty_QTBUG56830_data()
|
||||
{
|
||||
QTest::addColumn<QString>("key");
|
||||
QTest::addColumn<QString>("lookup");
|
||||
|
||||
QTest::newRow("bugreport-1") << QStringLiteral("240000000000") << QStringLiteral("3776798720");
|
||||
QTest::newRow("bugreport-2") << QStringLiteral("240000000001") << QStringLiteral("3776798721");
|
||||
QTest::newRow("biggest-ok-before-bug") << QStringLiteral("238609294221") << QStringLiteral("2386092941");
|
||||
QTest::newRow("smallest-bugged") << QStringLiteral("238609294222") << QStringLiteral("2386092942");
|
||||
QTest::newRow("biggest-bugged") << QStringLiteral("249108103166") << QStringLiteral("12884901886");
|
||||
QTest::newRow("smallest-ok-after-bug") << QStringLiteral("249108103167") << QStringLiteral("12884901887");
|
||||
}
|
||||
|
||||
void tst_QJSValue::hasProperty_QTBUG56830()
|
||||
{
|
||||
QFETCH(QString, key);
|
||||
QFETCH(QString, lookup);
|
||||
|
||||
QJSEngine eng;
|
||||
const QJSValue value(42);
|
||||
|
||||
QJSValue obj = eng.newObject();
|
||||
obj.setProperty(key, value);
|
||||
QVERIFY(obj.hasProperty(key));
|
||||
QVERIFY(!obj.hasProperty(lookup));
|
||||
}
|
||||
|
||||
void tst_QJSValue::deleteProperty_basic()
|
||||
{
|
||||
QJSEngine eng;
|
||||
|
|
|
@ -97,6 +97,8 @@ private slots:
|
|||
void hasProperty_basic();
|
||||
void hasProperty_globalObject();
|
||||
void hasProperty_changePrototype();
|
||||
void hasProperty_QTBUG56830_data();
|
||||
void hasProperty_QTBUG56830();
|
||||
|
||||
void deleteProperty_basic();
|
||||
void deleteProperty_globalObject();
|
||||
|
|
Loading…
Reference in New Issue