diff options
author | Simon Hausmann <simon.hausmann@qt.io> | 2018-03-09 16:40:38 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2018-03-20 09:44:11 +0000 |
commit | 64e90f393146dadb382d154e7d67a9109ab2492a (patch) | |
tree | c1079ff6af2c9fca9357a9313fffe5590e30dfce /tests/auto/qml/qmlcachegen | |
parent | 22b13921f8067f8a93164875a4ad59bed85b0400 (diff) |
Fix QML data structure version checking for ahead-of-time generated files
We must also do version checking for QML and JS files that were compiled
ahead of time and are embedded in resources. If the lookup for the
original source code fails, then we must generate an appropriate error
message.
As an upside we get better error reporting when trying to load an empty
file and Qt.include() now reports the error message in the statusText
field.
The error reporting for imported scripts was not changed as importing an
empty script is (oddly) allowed.
Task-number: QTBUG-66986
Change-Id: Ie0ef81af371a51ecf8c66ae7954d43f5cc6c12de
Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'tests/auto/qml/qmlcachegen')
-rw-r--r-- | tests/auto/qml/qmlcachegen/qmlcachegen.pro | 2 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp | 46 | ||||
-rw-r--r-- | tests/auto/qml/qmlcachegen/versionchecks.qml | 4 |
3 files changed, 52 insertions, 0 deletions
diff --git a/tests/auto/qml/qmlcachegen/qmlcachegen.pro b/tests/auto/qml/qmlcachegen/qmlcachegen.pro index a8b72224ba..bad912c781 100644 --- a/tests/auto/qml/qmlcachegen/qmlcachegen.pro +++ b/tests/auto/qml/qmlcachegen/qmlcachegen.pro @@ -8,4 +8,6 @@ workerscripts_test.files = worker.js worker.qml workerscripts_test.prefix = /workerscripts RESOURCES += workerscripts_test +RESOURCES += versionchecks.qml + QT += core-private qml-private testlib diff --git a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp index e36edca699..1c05005c90 100644 --- a/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp +++ b/tests/auto/qml/qmlcachegen/tst_qmlcachegen.cpp @@ -33,6 +33,7 @@ #include <QProcess> #include <QLibraryInfo> #include <QSysInfo> +#include <QLoggingCategory> #include <private/qqmlcomponent_p.h> class tst_qmlcachegen: public QObject @@ -48,6 +49,7 @@ private slots: void errorOnArgumentsInSignalHandler(); void aheadOfTimeCompilation(); void functionExpressions(); + void versionChecksForAheadOfTimeUnits(); void workerScripts(); }; @@ -280,6 +282,50 @@ void tst_qmlcachegen::aheadOfTimeCompilation() QCOMPARE(result.toInt(), 42); } +static QQmlPrivate::CachedQmlUnit *temporaryModifiedCachedUnit = nullptr; + +void tst_qmlcachegen::versionChecksForAheadOfTimeUnits() +{ + QVERIFY(QFile::exists(":/versionchecks.qml")); + QCOMPARE(QFileInfo(":/versionchecks.qml").size(), 0); + + Q_ASSERT(!temporaryModifiedCachedUnit); + QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError; + const QV4::CompiledData::Unit *originalUnit = QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error); + QVERIFY(originalUnit); + QV4::CompiledData::Unit *tweakedUnit = (QV4::CompiledData::Unit *)malloc(originalUnit->unitSize); + memcpy(reinterpret_cast<void *>(tweakedUnit), reinterpret_cast<const void *>(originalUnit), originalUnit->unitSize); + tweakedUnit->version = QV4_DATA_STRUCTURE_VERSION - 1; + temporaryModifiedCachedUnit = new QQmlPrivate::CachedQmlUnit{tweakedUnit, nullptr, nullptr}; + + auto testHandler = [](const QUrl &url) -> const QQmlPrivate::CachedQmlUnit * { + if (url == QUrl("qrc:/versionchecks.qml")) + return temporaryModifiedCachedUnit; + return nullptr; + }; + QQmlMetaType::prependCachedUnitLookupFunction(testHandler); + + { + QQmlMetaType::CachedUnitLookupError error = QQmlMetaType::CachedUnitLookupError::NoError; + QVERIFY(!QQmlMetaType::findCachedCompilationUnit(QUrl("qrc:/versionchecks.qml"), &error)); + QCOMPARE(error, QQmlMetaType::CachedUnitLookupError::VersionMismatch); + } + + { + QQmlEngine engine; + QQmlComponent component(&engine, QUrl("qrc:/versionchecks.qml")); + QCOMPARE(component.status(), QQmlComponent::Error); + QCOMPARE(component.errorString(), QString("qrc:/versionchecks.qml:-1 File was compiled ahead of time with an incompatible version of Qt and the original file cannot be found. Please recompile\n")); + } + + Q_ASSERT(temporaryModifiedCachedUnit); + free(const_cast<QV4::CompiledData::Unit *>(temporaryModifiedCachedUnit->qmlData)); + delete temporaryModifiedCachedUnit; + temporaryModifiedCachedUnit = nullptr; + + QQmlMetaType::removeCachedUnitLookupFunction(testHandler); +} + void tst_qmlcachegen::workerScripts() { QVERIFY(QFile::exists(":/workerscripts/worker.js")); diff --git a/tests/auto/qml/qmlcachegen/versionchecks.qml b/tests/auto/qml/qmlcachegen/versionchecks.qml new file mode 100644 index 0000000000..77d67e7da4 --- /dev/null +++ b/tests/auto/qml/qmlcachegen/versionchecks.qml @@ -0,0 +1,4 @@ +import QtQml 2.0 +QtObject { + property bool ok: true +} |