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 /src/qml/compiler | |
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 'src/qml/compiler')
-rw-r--r-- | src/qml/compiler/qv4compilationunitmapper.cpp | 32 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilationunitmapper_p.h | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilationunitmapper_unix.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compilationunitmapper_win.cpp | 2 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 38 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 2 |
6 files changed, 42 insertions, 36 deletions
diff --git a/src/qml/compiler/qv4compilationunitmapper.cpp b/src/qml/compiler/qv4compilationunitmapper.cpp index d94f7ac238..350f6f9485 100644 --- a/src/qml/compiler/qv4compilationunitmapper.cpp +++ b/src/qml/compiler/qv4compilationunitmapper.cpp @@ -59,36 +59,4 @@ CompilationUnitMapper::~CompilationUnitMapper() close(); } -bool CompilationUnitMapper::verifyHeader(const CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString) -{ - if (strncmp(header->magic, CompiledData::magic_str, sizeof(header->magic))) { - *errorString = QStringLiteral("Magic bytes in the header do not match"); - return false; - } - - if (header->version != quint32(QV4_DATA_STRUCTURE_VERSION)) { - *errorString = QString::fromUtf8("V4 data structure version mismatch. Found %1 expected %2").arg(header->version, 0, 16).arg(QV4_DATA_STRUCTURE_VERSION, 0, 16); - return false; - } - - if (header->qtVersion != quint32(QT_VERSION)) { - *errorString = QString::fromUtf8("Qt version mismatch. Found %1 expected %2").arg(header->qtVersion, 0, 16).arg(QT_VERSION, 0, 16); - return false; - } - - if (header->sourceTimeStamp) { - // Files from the resource system do not have any time stamps, so fall back to the application - // executable. - if (!sourceTimeStamp.isValid()) - sourceTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); - - if (sourceTimeStamp.isValid() && sourceTimeStamp.toMSecsSinceEpoch() != header->sourceTimeStamp) { - *errorString = QStringLiteral("QML source file has a different time stamp than cached file."); - return false; - } - } - - return true; -} - QT_END_NAMESPACE diff --git a/src/qml/compiler/qv4compilationunitmapper_p.h b/src/qml/compiler/qv4compilationunitmapper_p.h index b24f98df7c..80f914c141 100644 --- a/src/qml/compiler/qv4compilationunitmapper_p.h +++ b/src/qml/compiler/qv4compilationunitmapper_p.h @@ -72,8 +72,6 @@ public: void close(); private: - static bool verifyHeader(const QV4::CompiledData::Unit *header, QDateTime sourceTimeStamp, QString *errorString); - #if defined(Q_OS_UNIX) size_t length; #endif diff --git a/src/qml/compiler/qv4compilationunitmapper_unix.cpp b/src/qml/compiler/qv4compilationunitmapper_unix.cpp index 38dabc41cf..8348613888 100644 --- a/src/qml/compiler/qv4compilationunitmapper_unix.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_unix.cpp @@ -73,7 +73,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!verifyHeader(&header, sourceTimeStamp, errorString)) + if (!header.verifyHeader(sourceTimeStamp, errorString)) return nullptr; // Data structure and qt version matched, so now we can access the rest of the file safely. diff --git a/src/qml/compiler/qv4compilationunitmapper_win.cpp b/src/qml/compiler/qv4compilationunitmapper_win.cpp index d7a93ae233..8b000021f8 100644 --- a/src/qml/compiler/qv4compilationunitmapper_win.cpp +++ b/src/qml/compiler/qv4compilationunitmapper_win.cpp @@ -87,7 +87,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!verifyHeader(&header, sourceTimeStamp, errorString)) + if (!header.verifyHeader(sourceTimeStamp, errorString)) return nullptr; const uint mappingFlags = header.flags & QV4::CompiledData::Unit::ContainsMachineCode diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index cc11b250f3..6220c1bc11 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -755,6 +755,44 @@ void Unit::generateChecksum() #endif } +bool Unit::verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) const +{ +#ifndef V4_BOOTSTRAP + if (strncmp(magic, CompiledData::magic_str, sizeof(magic))) { + *errorString = QStringLiteral("Magic bytes in the header do not match"); + return false; + } + + if (version != quint32(QV4_DATA_STRUCTURE_VERSION)) { + *errorString = QString::fromUtf8("V4 data structure version mismatch. Found %1 expected %2").arg(version, 0, 16).arg(QV4_DATA_STRUCTURE_VERSION, 0, 16); + return false; + } + + if (qtVersion != quint32(QT_VERSION)) { + *errorString = QString::fromUtf8("Qt version mismatch. Found %1 expected %2").arg(qtVersion, 0, 16).arg(QT_VERSION, 0, 16); + return false; + } + + if (sourceTimeStamp) { + // Files from the resource system do not have any time stamps, so fall back to the application + // executable. + if (!expectedSourceTimeStamp.isValid()) + expectedSourceTimeStamp = QFileInfo(QCoreApplication::applicationFilePath()).lastModified(); + + if (expectedSourceTimeStamp.isValid() && expectedSourceTimeStamp.toMSecsSinceEpoch() != sourceTimeStamp) { + *errorString = QStringLiteral("QML source file has a different time stamp than cached file."); + return false; + } + } + + return true; +#else + Q_UNUSED(expectedSourceTimeStamp) + Q_UNUSED(errorString) + return false; +#endif +} + } } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index e6c4225bbd..49360bc3f1 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -727,6 +727,8 @@ struct Unit quint32_le padding; + bool verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) const; + const Import *importAt(int idx) const { return reinterpret_cast<const Import*>((reinterpret_cast<const char *>(this)) + offsetToImports + idx * sizeof(Import)); } |