aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-03-12 16:33:01 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-03-20 09:44:15 +0000
commit80592dcf0df3bce6177e8e051e88af7b9e6b3f6e (patch)
tree2b7f68ef624bb0913e35fa56f5d7326a806217c1 /src/qml
parent64e90f393146dadb382d154e7d67a9109ab2492a (diff)
Tighten QML cache version checking
Don't just include the "compile hash" of QtQml in the dependencies hash of QML files but use a dedicated field in the data structure, that we will also fill in when generating cache files ahead of time. This ensures that AOT generated cache files are considered invalid even when switching between different sha1s of declarative. Task-number: QTBUG-66986 Change-Id: I3d8ee103fd1a33a5b4c4576b3a2703fcd09712dd Reviewed-by: Erik Verbruggen <erik.verbruggen@qt.io>
Diffstat (limited to 'src/qml')
-rw-r--r--src/qml/compiler/compiler.pri2
-rw-r--r--src/qml/compiler/qv4compileddata.cpp45
-rw-r--r--src/qml/compiler/qv4compileddata_p.h6
-rw-r--r--src/qml/compiler/qv4compiler.cpp4
-rw-r--r--src/qml/qml.pro3
5 files changed, 21 insertions, 39 deletions
diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri
index 2ca0c39acc..95096db51d 100644
--- a/src/qml/compiler/compiler.pri
+++ b/src/qml/compiler/compiler.pri
@@ -40,8 +40,6 @@ SOURCES += \
unix: SOURCES += $$PWD/qv4compilationunitmapper_unix.cpp
else: SOURCES += $$PWD/qv4compilationunitmapper_win.cpp
-
-qtConfig(private_tests):qtConfig(dlopen): QMAKE_USE_PRIVATE += libdl
}
gcc {
diff --git a/src/qml/compiler/qv4compileddata.cpp b/src/qml/compiler/qv4compileddata.cpp
index 6220c1bc11..8dcc068a06 100644
--- a/src/qml/compiler/qv4compileddata.cpp
+++ b/src/qml/compiler/qv4compileddata.cpp
@@ -70,18 +70,14 @@
#include <algorithm>
-#if defined(QT_BUILD_INTERNAL)
-#if defined(Q_OS_UNIX) && !defined(QT_NO_DYNAMIC_CAST)
-#include <dlfcn.h>
-#endif
-#endif
-
QT_BEGIN_NAMESPACE
namespace QV4 {
namespace CompiledData {
+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");
+
#if !defined(V4_BOOTSTRAP)
static QString cacheFilePath(const QUrl &url)
{
@@ -686,32 +682,6 @@ void ResolvedTypeReference::doDynamicTypeCheck()
isFullyDynamicType = qtTypeInherits<QQmlPropertyMap>(mo);
}
-static QByteArray ownLibraryChecksum()
-{
- static QByteArray libraryChecksum;
- static bool checksumInitialized = false;
- if (checksumInitialized)
- return libraryChecksum;
- checksumInitialized = true;
-#if defined(QT_BUILD_INTERNAL) && !defined(QT_NO_DYNAMIC_CAST) && QT_CONFIG(dlopen)
- // This is a bit of a hack to make development easier. When hacking on the code generator
- // the cache files may end up being re-used. To avoid that we also add the checksum of
- // the QtQml library.
- Dl_info libInfo;
- if (dladdr(reinterpret_cast<void *>(&ownLibraryChecksum), &libInfo) != 0) {
- QFile library(QFile::decodeName(libInfo.dli_fname));
- if (library.open(QIODevice::ReadOnly)) {
- QCryptographicHash hash(QCryptographicHash::Md5);
- hash.addData(&library);
- libraryChecksum = hash.result();
- }
- }
-#else
- libraryChecksum = QByteArray(QML_COMPILE_HASH);
-#endif
- return libraryChecksum;
-}
-
bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *engine) const
{
for (auto it = constBegin(), end = constEnd(); it != end; ++it) {
@@ -719,8 +689,6 @@ bool ResolvedTypeReferenceMap::addToHash(QCryptographicHash *hash, QQmlEngine *e
return false;
}
- hash->addData(ownLibraryChecksum());
-
return true;
}
@@ -785,6 +753,15 @@ bool Unit::verifyHeader(QDateTime expectedSourceTimeStamp, QString *errorString)
}
}
+#if defined(QML_COMPILE_HASH)
+ if (qstrcmp(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;
#else
Q_UNUSED(expectedSourceTimeStamp)
diff --git a/src/qml/compiler/qv4compileddata_p.h b/src/qml/compiler/qv4compileddata_p.h
index 49360bc3f1..1df9d6794f 100644
--- a/src/qml/compiler/qv4compileddata_p.h
+++ b/src/qml/compiler/qv4compileddata_p.h
@@ -72,7 +72,7 @@
QT_BEGIN_NAMESPACE
// Bump this whenever the compiler data structures change in an incompatible way.
-#define QV4_DATA_STRUCTURE_VERSION 0x18
+#define QV4_DATA_STRUCTURE_VERSION 0x19
class QIODevice;
class QQmlPropertyCache;
@@ -688,6 +688,8 @@ struct Unit
quint32_le unitSize; // Size of the Unit and any depending data.
// END DO NOT CHANGE THESE FIELDS EVER
+ char libraryVersionHash[48];
+
char md5Checksum[16]; // checksum of all bytes following this field.
void generateChecksum();
@@ -793,7 +795,7 @@ struct Unit
}
};
-static_assert(sizeof(Unit) == 144, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
+static_assert(sizeof(Unit) == 192, "Unit structure needs to have the expected size to be binary compatible on disk when generated by host compiler and loaded by target");
struct TypeReference
{
diff --git a/src/qml/compiler/qv4compiler.cpp b/src/qml/compiler/qv4compiler.cpp
index ccc909c199..c9e535c93f 100644
--- a/src/qml/compiler/qv4compiler.cpp
+++ b/src/qml/compiler/qv4compiler.cpp
@@ -48,6 +48,9 @@
#include <wtf/MathExtras.h>
#include <QCryptographicHash>
+// generated by qmake:
+#include "qml_compile_hash_p.h"
+
QV4::Compiler::StringTableGenerator::StringTableGenerator()
{
clear();
@@ -396,6 +399,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, QML_COMPILE_HASH);
memset(unit.md5Checksum, 0, sizeof(unit.md5Checksum));
memset(unit.dependencyMD5Checksum, 0, sizeof(unit.dependencyMD5Checksum));
diff --git a/src/qml/qml.pro b/src/qml/qml.pro
index f75bfa0313..2137877427 100644
--- a/src/qml/qml.pro
+++ b/src/qml/qml.pro
@@ -36,7 +36,8 @@ DEFINES += QT_NO_FOREACH
}
compile_hash_contents = \
"// Generated file, DO NOT EDIT" \
- "$${LITERAL_HASH}define QML_COMPILE_HASH \"$$QML_COMPILE_HASH\""
+ "$${LITERAL_HASH}define QML_COMPILE_HASH \"$$QML_COMPILE_HASH\"" \
+ "$${LITERAL_HASH}define QML_COMPILE_HASH_LENGTH $$str_size($$QML_COMPILE_HASH)"
write_file("$$OUT_PWD/qml_compile_hash_p.h", compile_hash_contents)|error()
}