diff options
author | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-02-07 09:57:02 +0100 |
---|---|---|
committer | Fabian Kosmale <fabian.kosmale@qt.io> | 2020-02-07 09:14:15 +0000 |
commit | 19cc92d170eaba83812be2abda15348ecfa2f072 (patch) | |
tree | ce6acb445f44353f740308d4740d7df5a1516e7f | |
parent | 6420ad91d30e0cc3c2b7500d7c4b4bf1fce7c771 (diff) |
QV4Engine: Do not construct invalid QVariant
If the provided typeHint is -1, it does not make sense to construct a
QVariant of this type and to check whether it is appendable.
Fixes: QTBUG-81945
Change-Id: I32cbb9e70e210a7eca8d55801c1783338d1173b7
Reviewed-by: Ulf Hermann <ulf.hermann@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4engine.cpp | 40 | ||||
-rw-r--r-- | tests/auto/qml/qjsvalue/tst_qjsvalue.cpp | 7 |
2 files changed, 27 insertions, 20 deletions
diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 81f55673cd..d885c28166 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -1515,27 +1515,29 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int if (succeeded) return retn; #endif - retn = QVariant(typeHint, QMetaType::create(typeHint)); - auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>(); - if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) { - auto const length = a->getLength(); - QV4::ScopedValue arrayValue(scope); - for (qint64 i = 0; i < length; ++i) { - arrayValue = a->get(i); - QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects); - auto originalType = asVariant.userType(); - bool couldConvert = asVariant.convert(retnAsIterable._metaType_id); - if (!couldConvert) { - qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3") - .arg(QString::number(i), - QMetaType::typeName(originalType), - QMetaType::typeName(retnAsIterable._metaType_id)); - // create default constructed value - asVariant = QVariant(retnAsIterable._metaType_id, nullptr); + if (typeHint != -1) { + retn = QVariant(typeHint, QMetaType::create(typeHint)); + auto retnAsIterable = retn.value<QtMetaTypePrivate::QSequentialIterableImpl>(); + if (retnAsIterable._iteratorCapabilities & QtMetaTypePrivate::ContainerIsAppendable) { + auto const length = a->getLength(); + QV4::ScopedValue arrayValue(scope); + for (qint64 i = 0; i < length; ++i) { + arrayValue = a->get(i); + QVariant asVariant = toVariant(e, arrayValue, retnAsIterable._metaType_id, false, visitedObjects); + auto originalType = asVariant.userType(); + bool couldConvert = asVariant.convert(retnAsIterable._metaType_id); + if (!couldConvert) { + qWarning() << QLatin1String("Could not convert array value at position %1 from %2 to %3") + .arg(QString::number(i), + QMetaType::typeName(originalType), + QMetaType::typeName(retnAsIterable._metaType_id)); + // create default constructed value + asVariant = QVariant(retnAsIterable._metaType_id, nullptr); + } + retnAsIterable.append(asVariant.constData()); } - retnAsIterable.append(asVariant.constData()); + return retn; } - return retn; } } diff --git a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp index 95f554776f..cab4686c37 100644 --- a/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp +++ b/tests/auto/qml/qjsvalue/tst_qjsvalue.cpp @@ -1128,6 +1128,10 @@ void tst_QJSValue::toVariant() // array { + auto handler = qInstallMessageHandler([](QtMsgType type, const QMessageLogContext &, const QString &) { + if (type == QtMsgType::QtWarningMsg) + QFAIL("Converting QJSValue to QVariant should not cause error messages"); + }); QVariantList listIn; listIn << 123 << "hello"; QJSValue array = eng.toScriptValue(listIn); @@ -1145,8 +1149,9 @@ void tst_QJSValue::toVariant() QCOMPARE(array2.property("length").toInt(), array.property("length").toInt()); for (int i = 0; i < array.property("length").toInt(); ++i) QVERIFY(array2.property(i).strictlyEquals(array.property(i))); - } + qInstallMessageHandler(handler); + } } void tst_QJSValue::toQObject_nonQObject_data() |