From 673be1a3f8d28474d830762e46c7157a54ef3c39 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Thu, 5 Mar 2015 10:33:01 +0100 Subject: [PATCH] MimeDatabase: Do not crash/assert on invalid mime magic data Change-Id: I355241e472b1bb379ccc94fdd896c6d894206b0a Reviewed-by: Eike Ziller --- src/libs/utils/mimetypes/mimemagicrule.cpp | 46 ++++++++++++++++----- src/libs/utils/mimetypes/mimemagicrule_p.h | 3 +- src/libs/utils/mimetypes/mimetypeparser.cpp | 10 ++--- 3 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/libs/utils/mimetypes/mimemagicrule.cpp b/src/libs/utils/mimetypes/mimemagicrule.cpp index 397bf23c903..6fa471f2cad 100644 --- a/src/libs/utils/mimetypes/mimemagicrule.cpp +++ b/src/libs/utils/mimetypes/mimemagicrule.cpp @@ -233,14 +233,13 @@ QByteArray MimeMagicRule::makePattern(const QByteArray &value) } MimeMagicRule::MimeMagicRule(MimeMagicRule::Type theType, - const QByteArray &theValue, - int theStartPos, - int theEndPos, - const QByteArray &theMask) : + const QByteArray &theValue, + int theStartPos, + int theEndPos, + const QByteArray &theMask, + QString *errorString) : d(new MimeMagicRulePrivate) { - Q_ASSERT(!theValue.isEmpty()); - d->type = theType; d->value = theValue; d->startPos = theStartPos; @@ -248,10 +247,23 @@ MimeMagicRule::MimeMagicRule(MimeMagicRule::Type theType, d->mask = theMask; d->matchFunction = 0; + if (d->value.isEmpty()) { + d->type = Invalid; + if (errorString) + *errorString = QLatin1String("Invalid empty magic rule value"); + return; + } + if (d->type >= Host16 && d->type <= Byte) { bool ok; d->number = d->value.toUInt(&ok, 0); // autodetect - Q_ASSERT(ok); + if (!ok) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule value \"%1\"").arg( + QString::fromLatin1(d->value)); + return; + } d->numberMask = !d->mask.isEmpty() ? d->mask.toUInt(&ok, 0) : 0; // autodetect } @@ -260,9 +272,23 @@ MimeMagicRule::MimeMagicRule(MimeMagicRule::Type theType, d->pattern = makePattern(d->value); d->pattern.squeeze(); if (!d->mask.isEmpty()) { - Q_ASSERT(d->mask.size() >= 4 && d->mask.startsWith("0x")); - d->mask = QByteArray::fromHex(QByteArray::fromRawData(d->mask.constData() + 2, d->mask.size() - 2)); - Q_ASSERT(d->mask.size() == d->pattern.size()); + if (d->mask.size() < 4 || !d->mask.startsWith("0x")) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule mask \"%1\"").arg( + QString::fromLatin1(d->mask)); + return; + } + const QByteArray &tempMask = QByteArray::fromHex(QByteArray::fromRawData( + d->mask.constData() + 2, d->mask.size() - 2)); + if (tempMask.size() != d->pattern.size()) { + d->type = Invalid; + if (errorString) + *errorString = QString::fromLatin1("Invalid magic rule mask size \"%1\"").arg( + QString::fromLatin1(d->mask)); + return; + } + d->mask = tempMask; } else { d->mask.fill(char(-1), d->pattern.size()); } diff --git a/src/libs/utils/mimetypes/mimemagicrule_p.h b/src/libs/utils/mimetypes/mimemagicrule_p.h index 495d2167043..b1ebe1060ce 100644 --- a/src/libs/utils/mimetypes/mimemagicrule_p.h +++ b/src/libs/utils/mimetypes/mimemagicrule_p.h @@ -65,7 +65,8 @@ class QTCREATOR_UTILS_EXPORT MimeMagicRule public: enum Type { Invalid = 0, String, Host16, Host32, Big16, Big32, Little16, Little32, Byte }; - MimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos, const QByteArray &mask = QByteArray()); + MimeMagicRule(Type type, const QByteArray &value, int startPos, int endPos, + const QByteArray &mask = QByteArray(), QString *errorString = 0); MimeMagicRule(const MimeMagicRule &other); ~MimeMagicRule(); diff --git a/src/libs/utils/mimetypes/mimetypeparser.cpp b/src/libs/utils/mimetypes/mimetypeparser.cpp index 2b953a9168f..c1db64fb5c4 100644 --- a/src/libs/utils/mimetypes/mimetypeparser.cpp +++ b/src/libs/utils/mimetypes/mimetypeparser.cpp @@ -176,10 +176,6 @@ static bool createMagicMatchRule(const QXmlStreamAttributes &atts, return true; } const QString value = atts.value(QLatin1String(matchValueAttributeC)).toString(); - if (value.isEmpty()) { - *errorMessage = QString::fromLatin1("Empty match value detected."); - return false; - } // Parse for offset as "1" or "1:10" int startPos, endPos; const QString offsetS = atts.value(QLatin1String(matchOffsetAttributeC)).toString(); @@ -190,8 +186,12 @@ static bool createMagicMatchRule(const QXmlStreamAttributes &atts, return false; const QString mask = atts.value(QLatin1String(matchMaskAttributeC)).toString(); - rule = new MimeMagicRule(magicType, value.toUtf8(), startPos, endPos, mask.toLatin1()); + MimeMagicRule *tempRule = new MimeMagicRule(magicType, value.toUtf8(), startPos, endPos, + mask.toLatin1(), errorMessage); + if (!tempRule->isValid()) + return false; + rule = tempRule; return true; } #endif