diff options
author | Thiago Macieira <thiago.macieira@intel.com> | 2018-06-26 22:46:49 -0700 |
---|---|---|
committer | Thiago Macieira <thiago.macieira@intel.com> | 2018-09-01 15:19:39 +0000 |
commit | d9766ddc3d525cf08acec4c3483e61d86c9899a8 (patch) | |
tree | 755b9c9181a24cbc1663714e888e2e3f4cd4db45 /src/corelib/plugin/qlibrary.cpp | |
parent | 7391662f80470549b9f9c182da43cf433efabdf7 (diff) | |
download | qtbase-d9766ddc3d525cf08acec4c3483e61d86c9899a8.tar.gz |
Plugins: store the metadata in CBOR instead of binary JSON
In preparation for Qt 6 deprecating the binary JSON format. Also reduces
the size of the metadata a little: for the xcb platform plugin, it went
down from 264 bytes to 138; for the jpeg image plugin, it went from 320
to 135.
I've had to change the signature so older versions of Qt won't try to
parse the CBOR data as Binary JSON. Unfortunately, before QJsonDocument
could get a chance to reject it, qJsonFromRawLibraryMetaData() needed to
allocate memory and that causes crashes with Qt < 5.11.2.
Change-Id: Ieb48f7c0dd0e4e0fb35efffd153bee34e16ce347
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
Diffstat (limited to 'src/corelib/plugin/qlibrary.cpp')
-rw-r--r-- | src/corelib/plugin/qlibrary.cpp | 44 |
1 files changed, 26 insertions, 18 deletions
diff --git a/src/corelib/plugin/qlibrary.cpp b/src/corelib/plugin/qlibrary.cpp index 869ef6181f..aa63ed1a6b 100644 --- a/src/corelib/plugin/qlibrary.cpp +++ b/src/corelib/plugin/qlibrary.cpp @@ -268,7 +268,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) */ bool hasMetaData = false; qsizetype pos = 0; - char pattern[] = "qTMETADATA "; + char pattern[] = "qTMETADATA "; pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it. const ulong plen = qstrlen(pattern); #if defined (Q_OF_ELF) && defined(Q_CC_GNU) @@ -314,10 +314,14 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib) bool ret = false; - if (pos >= 0) { - if (hasMetaData) { - const char *data = filedata + pos; - QJsonDocument doc = qJsonFromRawLibraryMetaData(data, qsizetype(fdlen)); + if (pos >= 0 && hasMetaData) { + const char *data = filedata + pos; + QString errMsg; + QJsonDocument doc = qJsonFromRawLibraryMetaData(data, fdlen, &errMsg); + if (doc.isNull()) { + qWarning("Found invalid metadata in lib %s: %s", + qPrintable(library), qPrintable(errMsg)); + } else { lib->metaData = doc.object(); if (qt_debug_component()) qWarning("Found metadata in lib %s, metadata=\n%s\n", @@ -679,20 +683,26 @@ bool QLibrary::isLibrary(const QString &fileName) #endif } -typedef const char * (*QtPluginQueryVerificationDataFunction)(); - -static bool qt_get_metadata(QtPluginQueryVerificationDataFunction pfn, QLibraryPrivate *priv) +static bool qt_get_metadata(QLibraryPrivate *priv, QString *errMsg) { - const char *szData = 0; - if (!pfn) - return false; +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + auto getMetaData = [](QFunctionPointer fptr) { + auto f = reinterpret_cast<const char * (*)()>(fptr); + return qMakePair<const char *, size_t>(f(), INT_MAX); + }; +#else + auto getMetaData = [](QFunctionPointer fptr) { + auto f = reinterpret_cast<QPair<const char *, size_t> (*)()>(fptr); + return f(); + }; +#endif - szData = pfn(); - if (!szData) + QFunctionPointer pfn = priv->resolve("qt_plugin_query_metadata"); + if (!pfn) return false; - // the data is already loaded, so the size doesn't matter - QJsonDocument doc = qJsonFromRawLibraryMetaData(szData, INT_MAX); + auto metaData = getMetaData(pfn); + QJsonDocument doc = qJsonFromRawLibraryMetaData(metaData.first, metaData.second, errMsg); if (doc.isNull()) return false; priv->metaData = doc.object(); @@ -735,9 +745,7 @@ void QLibraryPrivate::updatePluginState() } else { // library is already loaded (probably via QLibrary) // simply get the target function and call it. - QtPluginQueryVerificationDataFunction getMetaData = NULL; - getMetaData = (QtPluginQueryVerificationDataFunction) resolve("qt_plugin_query_metadata"); - success = qt_get_metadata(getMetaData, this); + success = qt_get_metadata(this, &errorString); } if (!success) { |