diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/qml/compiler/qv4compileddata.cpp | 57 | ||||
-rw-r--r-- | src/qml/compiler/qv4compileddata_p.h | 3 | ||||
-rw-r--r-- | src/qml/compiler/qv4compiler.cpp | 3 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4compilationunitmapper_unix.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4compilationunitmapper_win.cpp | 4 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit.cpp | 58 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4executablecompilationunit_p.h | 3 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 2 |
8 files changed, 68 insertions, 66 deletions
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp index ee413a906d..2cb24dc113 100644 --- a/src/qml/compiler/qv4compileddata.cpp +++ b/src/qml/compiler/qv4compileddata.cpp @@ -46,9 +46,6 @@ #include <QScopeGuard> #include <QFileInfo> -// generated by qmake: -#include "qml_compile_hash_p.h" - #include <algorithm> QT_BEGIN_NAMESPACE @@ -57,19 +54,6 @@ namespace QV4 { namespace CompiledData { -#if defined(QML_COMPILE_HASH) -# ifdef Q_OS_LINUX -// Place on a separate section on Linux so it's easier to check from outside -// what the hash version is. -__attribute__((section(".qml_compile_hash"))) -# endif -const char qml_compile_hash[48 + 1] = QML_COMPILE_HASH; -static_assert(sizeof(Unit::libraryVersionHash) >= QML_COMPILE_HASH_LENGTH + 1, "Compile hash length exceeds reserved size in data structure. Please adjust and bump the format version"); -#else -# error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files" -#endif - - CompilationUnit::CompilationUnit(const Unit *unitData, const QString &fileName, const QString &finalUrlString) { setUnitData(unitData, nullptr, fileName, finalUrlString); @@ -228,47 +212,6 @@ void Unit::generateChecksum() #endif } -bool Unit::verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) const -{ - 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; - } - } - -#if defined(QML_COMPILE_HASH) - if (qstrcmp(CompiledData::qml_compile_hash, libraryVersionHash) != 0) { - *errorString = QStringLiteral("QML library version mismatch. Expected compile hash does not match"); - return false; - } -#else -#error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files" -#endif - - return true; -} - } } diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h index cbc350a723..73db6f54e6 100644 --- a/src/qml/compiler/qv4compileddata_p.h +++ b/src/qml/compiler/qv4compileddata_p.h @@ -812,7 +812,6 @@ static_assert(sizeof(QmlUnit) == 16, "QmlUnit structure needs to have the expect enum { QmlCompileHashSpace = 48 }; static const char magic_str[] = "qv4cdata"; -extern const char qml_compile_hash[QmlCompileHashSpace + 1]; struct Unit { @@ -876,8 +875,6 @@ struct Unit quint32_le offsetToQmlUnit; - bool verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString) const; - /* QML specific fields */ const QmlUnit *qmlUnit() const { diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp index d8f293211e..592f5731ca 100644 --- a/src/qml/compiler/qv4compiler.cpp +++ b/src/qml/compiler/qv4compiler.cpp @@ -44,6 +44,7 @@ #include <private/qv4alloca_p.h> #include <private/qqmljslexer_p.h> #include <private/qqmljsast_p.h> +#include <private/qml_compile_hash_p.h> #include <QCryptographicHash> // Efficient implementation that takes advantage of powers of two. @@ -580,7 +581,7 @@ QV4::CompiledData::Unit QV4::Compiler::JSUnitGenerator::generateHeader(QV4::Comp unit.flags |= module->unitFlags; unit.version = QV4_DATA_STRUCTURE_VERSION; unit.qtVersion = QT_VERSION; - qstrcpy(unit.libraryVersionHash, CompiledData::qml_compile_hash); + qstrcpy(unit.libraryVersionHash, QML_COMPILE_HASH); memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum)); memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum)); diff --git a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp index 6768bc9596..a9ab2f5ccb 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp +++ b/src/qml/jsruntime/qv4compilationunitmapper_unix.cpp @@ -45,7 +45,7 @@ #include <QScopeGuard> #include <QDateTime> -#include "qv4compileddata_p.h" +#include "qv4executablecompilationunit_p.h" QT_BEGIN_NAMESPACE @@ -73,7 +73,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!header.verifyHeader(sourceTimeStamp, errorString)) + if (!ExecutableCompilationUnit::verifyHeader(&header, 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/jsruntime/qv4compilationunitmapper_win.cpp b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp index 779c1288fe..9e8babc5e6 100644 --- a/src/qml/jsruntime/qv4compilationunitmapper_win.cpp +++ b/src/qml/jsruntime/qv4compilationunitmapper_win.cpp @@ -39,7 +39,7 @@ #include "qv4compilationunitmapper_p.h" -#include "qv4compileddata_p.h" +#include "qv4executablecompilationunit_p.h" #include <QScopeGuard> #include <QFileInfo> #include <QDateTime> @@ -87,7 +87,7 @@ CompiledData::Unit *CompilationUnitMapper::open(const QString &cacheFileName, co return nullptr; } - if (!header.verifyHeader(sourceTimeStamp, errorString)) + if (!ExecutableCompilationUnit::verifyHeader(&header, 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/jsruntime/qv4executablecompilationunit.cpp b/src/qml/jsruntime/qv4executablecompilationunit.cpp index 58f6735008..7867dff769 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit.cpp +++ b/src/qml/jsruntime/qv4executablecompilationunit.cpp @@ -51,6 +51,7 @@ #include <private/qqmlvaluetypewrapper_p.h> #include <private/qv4module_p.h> #include <private/qv4compilationunitmapper_p.h> +#include <private/qml_compile_hash_p.h> #include <QtQml/qqmlfile.h> #include <QtQml/qqmlpropertymap.h> @@ -60,6 +61,19 @@ #include <QtCore/qfileinfo.h> #include <QtCore/qscopeguard.h> +#if defined(QML_COMPILE_HASH) +# ifdef Q_OS_LINUX +// Place on a separate section on Linux so it's easier to check from outside +// what the hash version is. +__attribute__((section(".qml_compile_hash"))) +# endif +const char qml_compile_hash[48 + 1] = QML_COMPILE_HASH; +static_assert(sizeof(QV4::CompiledData::Unit::libraryVersionHash) >= QML_COMPILE_HASH_LENGTH + 1, + "Compile hash length exceeds reserved size in data structure. Please adjust and bump the format version"); +#else +# error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files" +#endif + QT_BEGIN_NAMESPACE namespace QV4 { @@ -804,6 +818,50 @@ QString ExecutableCompilationUnit::bindingValueAsScriptString( : bindingValueAsString(binding); } +bool ExecutableCompilationUnit::verifyHeader( + const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp, QString *errorString) +{ + if (strncmp(unit->magic, CompiledData::magic_str, sizeof(unit->magic))) { + *errorString = QStringLiteral("Magic bytes in the header do not match"); + return false; + } + + if (unit->version != quint32(QV4_DATA_STRUCTURE_VERSION)) { + *errorString = QString::fromUtf8("V4 data structure version mismatch. Found %1 expected %2") + .arg(unit->version, 0, 16).arg(QV4_DATA_STRUCTURE_VERSION, 0, 16); + return false; + } + + if (unit->qtVersion != quint32(QT_VERSION)) { + *errorString = QString::fromUtf8("Qt version mismatch. Found %1 expected %2") + .arg(unit->qtVersion, 0, 16).arg(QT_VERSION, 0, 16); + return false; + } + + if (unit->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() != unit->sourceTimeStamp) { + *errorString = QStringLiteral("QML source file has a different time stamp than cached file."); + return false; + } + } + +#if defined(QML_COMPILE_HASH) + if (qstrcmp(qml_compile_hash, unit->libraryVersionHash) != 0) { + *errorString = QStringLiteral("QML library version mismatch. Expected compile hash does not match"); + return false; + } +#else +#error "QML_COMPILE_HASH must be defined for the build of QtDeclarative to ensure version checking for cache files" +#endif + return true; +} + } // namespace QV4 QT_END_NAMESPACE diff --git a/src/qml/jsruntime/qv4executablecompilationunit_p.h b/src/qml/jsruntime/qv4executablecompilationunit_p.h index 4e3aadf28a..1823a3663c 100644 --- a/src/qml/jsruntime/qv4executablecompilationunit_p.h +++ b/src/qml/jsruntime/qv4executablecompilationunit_p.h @@ -251,6 +251,9 @@ public: return constants[binding->value.constantValueIndex].doubleValue(); } + static bool verifyHeader(const CompiledData::Unit *unit, QDateTime expectedSourceTimeStamp, + QString *errorString); + protected: quint32 totalStringCount() const { return data->stringTableSize; } diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index a2c2ae47af..558b5d53c1 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -1330,7 +1330,7 @@ const QV4::CompiledData::Unit *QQmlMetaType::findCachedCompilationUnit(const QUr for (const auto lookup : qAsConst(data->lookupCachedQmlUnit)) { if (const QQmlPrivate::CachedQmlUnit *unit = lookup(uri)) { QString error; - if (!unit->qmlData->verifyHeader(QDateTime(), &error)) { + if (!QV4::ExecutableCompilationUnit::verifyHeader(unit->qmlData, QDateTime(), &error)) { qCDebug(DBG_DISK_CACHE) << "Error loading pre-compiled file " << uri << ":" << error; if (status) *status = CachedUnitLookupError::VersionMismatch; |