QPlugin: use one global metadata magic string

And use QByteArrayView where applicable.

Change-Id: I2de1b4dfacd443148279fffd16a39ec22908f75f
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
This commit is contained in:
Thiago Macieira 2021-09-10 18:00:46 -07:00
parent 788a7bfdb1
commit 16e7366b5c
2 changed files with 20 additions and 34 deletions

View File

@ -48,7 +48,6 @@
#include "private/qobject_p.h" #include "private/qobject_p.h"
#include "qcbormap.h" #include "qcbormap.h"
#include "qcborvalue.h" #include "qcborvalue.h"
#include "qendian.h"
#include "qjsonarray.h" #include "qjsonarray.h"
#include "qjsondocument.h" #include "qjsondocument.h"
#include "qjsonobject.h" #include "qjsonobject.h"
@ -65,24 +64,23 @@
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
static inline int metaDataSignatureLength() QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype size, QString *errMsg)
{ {
return sizeof("QTMETADATA ") - 1; Q_ASSERT(size >= qsizetype(sizeof(QPluginMetaData::MagicString)));
} raw += sizeof(QPluginMetaData::MagicString);
size -= sizeof(QPluginMetaData::MagicString);
static QJsonDocument jsonFromCborMetaData(const char *raw, qsizetype size, QString *errMsg)
{
// extract the keys not stored in CBOR // extract the keys not stored in CBOR
int qt_metadataVersion = quint8(raw[0]); QPluginMetaData::Header header;
int qt_version = qFromBigEndian<quint16>(raw + 1); Q_ASSERT(size >= qsizetype(sizeof(header)));
int qt_archRequirements = quint8(raw[3]); memcpy(&header, raw, sizeof(header));
if (Q_UNLIKELY(raw[-1] != '!' || qt_metadataVersion != 0)) { if (Q_UNLIKELY(header.version > QPluginMetaData::CurrentMetaDataVersion)) {
*errMsg = QStringLiteral("Invalid metadata version"); *errMsg = QStringLiteral("Invalid metadata version");
return QJsonDocument(); return QJsonDocument();
} }
raw += 4; raw += sizeof(header);
size -= 4; size -= sizeof(header);
QByteArray ba = QByteArray::fromRawData(raw, int(size)); QByteArray ba = QByteArray::fromRawData(raw, int(size));
QCborParserError err; QCborParserError err;
QCborValue metadata = QCborValue::fromCbor(ba, &err); QCborValue metadata = QCborValue::fromCbor(ba, &err);
@ -98,9 +96,10 @@ static QJsonDocument jsonFromCborMetaData(const char *raw, qsizetype size, QStri
} }
QJsonObject o; QJsonObject o;
o.insert(QLatin1String("version"), qt_version << 8); o.insert(QLatin1String("version"),
o.insert(QLatin1String("debug"), bool(qt_archRequirements & 1)); QT_VERSION_CHECK(header.qt_major_version, header.qt_minor_version, 0));
o.insert(QLatin1String("archreq"), qt_archRequirements); o.insert(QLatin1String("debug"), bool(header.plugin_arch_requirements & 1));
o.insert(QLatin1String("archreq"), header.plugin_arch_requirements);
// convert the top-level map integer keys // convert the top-level map integer keys
for (auto it : metadata.toMap()) { for (auto it : metadata.toMap()) {
@ -128,14 +127,6 @@ static QJsonDocument jsonFromCborMetaData(const char *raw, qsizetype size, QStri
return QJsonDocument(o); return QJsonDocument(o);
} }
QJsonDocument qJsonFromRawLibraryMetaData(const char *raw, qsizetype sectionSize, QString *errMsg)
{
raw += metaDataSignatureLength();
sectionSize -= metaDataSignatureLength();
return jsonFromCborMetaData(raw, sectionSize, errMsg);
}
class QFactoryLoaderPrivate : public QObjectPrivate class QFactoryLoaderPrivate : public QObjectPrivate
{ {
Q_DECLARE_PUBLIC(QFactoryLoader) Q_DECLARE_PUBLIC(QFactoryLoader)

View File

@ -1,7 +1,7 @@
/**************************************************************************** /****************************************************************************
** **
** Copyright (C) 2016 The Qt Company Ltd. ** Copyright (C) 2020 The Qt Company Ltd.
** Copyright (C) 2018 Intel Corporation. ** Copyright (C) 2021 Intel Corporation.
** Contact: https://www.qt.io/licensing/ ** Contact: https://www.qt.io/licensing/
** **
** This file is part of the QtCore module of the Qt Toolkit. ** This file is part of the QtCore module of the Qt Toolkit.
@ -182,9 +182,7 @@ QT_BEGIN_NAMESPACE
\sa loadHints \sa loadHints
*/ */
static qsizetype qt_find_pattern(const char *s, qsizetype s_len)
static qsizetype qt_find_pattern(const char *s, qsizetype s_len,
const char *pattern, ulong p_len)
{ {
/* /*
We used to search from the end of the file so we'd skip the code and find We used to search from the end of the file so we'd skip the code and find
@ -195,8 +193,8 @@ static qsizetype qt_find_pattern(const char *s, qsizetype s_len,
More importantly, the pattern string may exist in the debug information due More importantly, the pattern string may exist in the debug information due
to it being used in the plugin in the first place. to it being used in the plugin in the first place.
*/ */
QByteArrayView pattern = QPluginMetaData::MagicString;
static const QByteArrayMatcher matcher(QByteArray(pattern, p_len)); static const QByteArrayMatcher matcher(pattern.toByteArray());
return matcher.indexIn(s, s_len); return matcher.indexIn(s, s_len);
} }
@ -278,10 +276,7 @@ static bool findPatternUnloaded(const QString &library, QLibraryPrivate *lib)
} }
#endif // defined(Q_OF_ELF) && defined(Q_CC_GNU) #endif // defined(Q_OF_ELF) && defined(Q_CC_GNU)
char pattern[] = "qTMETADATA "; if (qsizetype rel = qt_find_pattern(filedata + r.pos, r.length);
pattern[0] = 'Q'; // Ensure the pattern "QTMETADATA" is not found in this library should QPluginLoader ever encounter it.
const ulong plen = ulong(qstrlen(pattern));
if (qsizetype rel = qt_find_pattern(filedata + r.pos, r.length, pattern, plen);
rel >= 0) { rel >= 0) {
const char *data = filedata + r.pos + rel; const char *data = filedata + r.pos + rel;
QString errMsg; QString errMsg;