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:
Giuseppe D'Angelo 2016-11-04 00:11:59 +01:00
parent 5861ea797d
commit 64714ea431
4 changed files with 39 additions and 4 deletions

View File

@ -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;
}

View File

@ -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,

View File

@ -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;

View File

@ -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();