Skip to content

Commit

Permalink
QFactoryLoader: rewrite parse() using the new iterateInPluginMetaData()
Browse files Browse the repository at this point in the history
This doesn't simplify the actual parsing or make it any faster, but does
merge the validation code so we only have it in one place.

Change-Id: I8bd6bb457b9c42218247fffd1797543bec9cfbec
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Eirik Aavitsland <eirik.aavitsland@qt.io>
Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
  • Loading branch information
thiagomacieira committed Nov 28, 2023
1 parent 4a432a7 commit 90df0f4
Showing 1 changed file with 34 additions and 20 deletions.
54 changes: 34 additions & 20 deletions src/corelib/plugin/qfactoryloader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ struct QFactoryLoaderIidSearch
{
QLatin1StringView iid;
bool matchesIid = false;
QFactoryLoaderIidSearch(QLatin1StringView iid) : iid(iid) {}
QFactoryLoaderIidSearch(QLatin1StringView iid) : iid(iid)
{ Q_ASSERT(!iid.isEmpty()); }

static QString readString(QCborStreamReader &reader)
{
Expand Down Expand Up @@ -93,7 +94,7 @@ struct QFactoryLoaderIidSearch
matchesIid = (readString(reader) == iid);
return IterationResult::FinishedSearch;
}
IterationResult::Result operator()(const QCborValue &, QCborStreamReader &reader)
IterationResult::Result operator()(const QString &, QCborStreamReader &reader)
{
return skip(reader);
}
Expand Down Expand Up @@ -129,11 +130,13 @@ template <typename F> static IterationResult iterateInPluginMetaData(QByteArrayV
if (!reader.next())
return reader.lastError();
r = f(key, reader);
} else {
QCborValue key = QCborValue::fromCbor(reader);
if (key.isInvalid())
} else if (reader.isString()) {
QString key = readString(reader);
if (key.isNull())
return reader.lastError();
r = f(key, reader);
} else {
return IterationResult::InvalidTopLevelItem;
}

if (QCborError e = reader.lastError())
Expand All @@ -156,24 +159,35 @@ static bool isIidMatch(QByteArrayView raw, QLatin1StringView iid)

bool QPluginParsedMetaData::parse(QByteArrayView raw)
{
QPluginMetaData::Header header;
Q_ASSERT(raw.size() >= qsizetype(sizeof(header)));
memcpy(&header, raw.data(), sizeof(header));
if (Q_UNLIKELY(header.version > QPluginMetaData::CurrentMetaDataVersion))
return setError(QFactoryLoader::tr("Invalid metadata version"));
QCborMap map;
auto r = iterateInPluginMetaData(raw, [&](const auto &key, QCborStreamReader &reader) {
QCborValue item = QCborValue::fromCbor(reader);
if (item.isInvalid())
return IterationResult::ParsingError;
if constexpr (std::is_enum_v<std::decay_t<decltype(key)>>)
map[int(key)] = item;
else
map[key] = item;
return IterationResult::ContinueSearch;
});

// use fromRawData to keep QCborStreamReader from copying
raw = raw.sliced(sizeof(header));
QByteArray ba = QByteArray::fromRawData(raw.data(), raw.size());
QCborParserError err;
QCborValue metadata = QCborValue::fromCbor(ba, &err);
switch (r.result) {
case IterationResult::FinishedSearch:
case IterationResult::ContinueSearch:
break;

if (err.error != QCborError::NoError)
return setError(QFactoryLoader::tr("Metadata parsing error: %1").arg(err.error.toString()));
if (!metadata.isMap())
// parse errors
case IterationResult::ParsingError:
return setError(QFactoryLoader::tr("Metadata parsing error: %1").arg(r.error.toString()));
case IterationResult::InvalidMetaDataVersion:
return setError(QFactoryLoader::tr("Invalid metadata version"));
case IterationResult::InvalidTopLevelItem:
case IterationResult::InvalidHeaderItem:
return setError(QFactoryLoader::tr("Unexpected metadata contents"));
QCborMap map = metadata.toMap();
metadata = {};
}

// header was validated
auto header = qFromUnaligned<QPluginMetaData::Header>(raw.data());

DecodedArchRequirements archReq =
header.version == 0 ? decodeVersion0ArchRequirements(header.plugin_arch_requirements)
Expand Down

0 comments on commit 90df0f4

Please sign in to comment.