aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/compiler
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@qt.io>2018-03-09 16:40:38 +0100
committerSimon Hausmann <simon.hausmann@qt.io>2018-03-20 09:44:11 +0000
commit64e90f393146dadb382d154e7d67a9109ab2492a (patch)
treec1079ff6af2c9fca9357a9313fffe5590e30dfce /src/qml/compiler
parent22b13921f8067f8a93164875a4ad59bed85b0400 (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.cpp32
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_p.h2
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_unix.cpp2
-rw-r--r--src/qml/compiler/qv4compilationunitmapper_win.cpp2
-rw-r--r--src/qml/compiler/qv4compileddata.cpp38
-rw-r--r--src/qml/compiler/qv4compileddata_p.h2
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));
}