diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp index 177895ff6c3..586a0c64373 100644 --- a/src/corelib/mimetypes/qmimeprovider.cpp +++ b/src/corelib/mimetypes/qmimeprovider.cpp @@ -213,22 +213,25 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM return; Q_ASSERT(m_cacheFile); const QString lowerFileName = fileName.toLower(); + int numMatches = 0; // Check literals (e.g. "Makefile") - matchGlobList(result, m_cacheFile.get(), m_cacheFile->getUint32(PosLiteralListOffset), - fileName); + numMatches = matchGlobList(result, m_cacheFile.get(), + m_cacheFile->getUint32(PosLiteralListOffset), fileName); // Check the very common *.txt cases with the suffix tree - if (result.m_matchingMimeTypes.isEmpty()) { + if (numMatches == 0) { const int reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset); const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset); const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4); - matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, lowerFileName, - lowerFileName.size() - 1, false); - if (result.m_matchingMimeTypes.isEmpty()) - matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, fileName, - fileName.size() - 1, true); + if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, lowerFileName, + lowerFileName.size() - 1, false)) { + ++numMatches; + } else if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, fileName, + fileName.size() - 1, true)) { + ++numMatches; + } } // Check complex globs (e.g. "callgrind.out[0-9]*" or "README*") - if (result.m_matchingMimeTypes.isEmpty()) + if (numMatches == 0) matchGlobList(result, m_cacheFile.get(), m_cacheFile->getUint32(PosGlobListOffset), fileName); } @@ -244,8 +247,10 @@ void QMimeBinaryProvider::excludeMimeTypeGlobs(const QStringList &toExclude) appendIfNew(m_mimeTypesWithExcludedGlobs, mt); } -void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, const QString &fileName) +int QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int off, + const QString &fileName) { + int numMatches = 0; const int numGlobs = cacheFile->getUint32(off); //qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset; for (int i = 0; i < numGlobs; ++i) { @@ -263,9 +268,12 @@ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile continue; QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive); - if (glob.matchFileName(fileName)) + if (glob.matchFileName(fileName)) { result.addMatch(QLatin1StringView(mimeType), weight, pattern); + ++numMatches; + } } + return numMatches; } bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index 1cd1a00f513..e498cf8c399 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -111,7 +111,8 @@ public: private: struct CacheFile; - void matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int offset, const QString &fileName); + int matchGlobList(QMimeGlobMatchResult &result, CacheFile *cacheFile, int offset, + const QString &fileName); bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries, int firstOffset, const QString &fileName, qsizetype charPos, bool caseSensitiveCheck); diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt index 92bc339ead8..d9e055380e5 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt @@ -32,6 +32,7 @@ set(testdata_resource_files "../qml-again.xml" "../test.qml" "../text-x-objcsrc.xml" + "../text-plain-subclass.xml" "../yast2-metapackage-handler-mimetypes.xml" ) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt index 49ff4d13805..e44ea7b5ebf 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt +++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt @@ -32,6 +32,7 @@ set(testdata_resource_files "../qml-again.xml" "../test.qml" "../text-x-objcsrc.xml" + "../text-plain-subclass.xml" "../yast2-metapackage-handler-mimetypes.xml" ) diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml b/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml new file mode 100644 index 00000000000..7b5cb7506d3 --- /dev/null +++ b/tests/auto/corelib/mimetypes/qmimedatabase/text-plain-subclass.xml @@ -0,0 +1,15 @@ + + + + MicroDVD subtitles + + + + + + + + + + + diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp index 9c680c84d99..ee9e430b911 100644 --- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp @@ -30,16 +30,15 @@ using namespace Qt::StringLiterals; -static const char *const additionalMimeFiles[] = { - "yast2-metapackage-handler-mimetypes.xml", - "qml-again.xml", - "text-x-objcsrc.xml", - "invalid-magic1.xml", - "invalid-magic2.xml", - "invalid-magic3.xml", - "magic-and-hierarchy.xml", - 0 -}; +static const char *const additionalMimeFiles[] = { "yast2-metapackage-handler-mimetypes.xml", + "qml-again.xml", + "text-x-objcsrc.xml", + "text-plain-subclass.xml", + "invalid-magic1.xml", + "invalid-magic2.xml", + "invalid-magic3.xml", + "magic-and-hierarchy.xml", + 0 }; static const auto s_resourcePrefix = ":/qt-project.org/qmime/"_L1; static const auto s_inodeMimetype = "inode/directory"_L1; @@ -1196,6 +1195,8 @@ void tst_QMimeDatabase::installNewLocalMimeType() QVERIFY(objcsrc.isValid()); QCOMPARE(objcsrc.globPatterns(), QStringList()); } + QCOMPARE(db.mimeTypeForFile(QLatin1String("foo.txt"), QMimeDatabase::MatchExtension).name(), + QString::fromLatin1("text/plain")); // Test that a double-definition of a mimetype doesn't lead to sniffing ("conflicting globs"). const QString qmlTestFile = s_resourcePrefix + "test.qml"_L1;