From 38b183fd9023ab9524e5a0a114712feef193c1c7 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 27 Feb 2015 16:02:25 +0100 Subject: [PATCH] MimeDatabase: Remove bestMatch, which was broken beyond repair The problem is that, if you check e.g. a .pro file against all C/C++ mime types, and these define magic matchers, it would find that .pro doesn't match C/C++ mime types by extension, so it would open the file to find a magic match. Even though the extension .pro would identify it already as a qmake .pro file when checking for the mime type globally. Change-Id: I3341187e88e2263bf38169c3c99e5d2161e2a9ee Reviewed-by: Daniel Teske Reviewed-by: Orgad Shaneh --- src/libs/utils/mimetypes/mimedatabase.cpp | 73 -------------------- src/libs/utils/mimetypes/mimedatabase.h | 1 - src/libs/utils/mimetypes/mimeprovider.cpp | 56 --------------- src/libs/utils/mimetypes/mimeprovider_p.h | 4 -- src/plugins/cpptools/cppprojectfile.cpp | 9 ++- src/plugins/cpptools/cppprojectfile.h | 1 - src/plugins/qmljstools/qmljsmodelmanager.cpp | 14 ++-- 7 files changed, 11 insertions(+), 147 deletions(-) diff --git a/src/libs/utils/mimetypes/mimedatabase.cpp b/src/libs/utils/mimetypes/mimedatabase.cpp index 680e180f0e3..39f3cf7a2a9 100644 --- a/src/libs/utils/mimetypes/mimedatabase.cpp +++ b/src/libs/utils/mimetypes/mimedatabase.cpp @@ -352,79 +352,6 @@ QStringList MimeDatabase::allGlobPatterns() return patterns; } -static MimeType mimeForName(const QList &types, const QString &name) -{ - foreach (const MimeType &mt, types) - if (mt.matchesName(name)) - return mt; - return MimeType(); -} - -MimeType MimeDatabase::bestMatch(const QString &fileName, const QList &types) -{ - // Copied together from mimeTypeForFile(QFileInfo) code path ... - // It would be better to be able to work on a list of mime types directly - - // Check for directory. We just ignore the code path for special unix nodes. - if (fileName.endsWith(QLatin1Char('/'))) - return mimeForName(types, QLatin1String("inode/directory")); - - auto d = MimeDatabasePrivate::instance(); - QMutexLocker locker(&d->mutex); - - QStringList candidatesByName = d->provider()->bestMatchByFileName(QFileInfo(fileName).fileName(), - types); - if (candidatesByName.count() == 1) { - MimeType mt = mimeForName(types, candidatesByName.first()); - if (mt.isValid()) - return mt; - candidatesByName.clear(); - } - // Extension is unknown, or matches multiple mimetypes. - // Pass 2) Match on content, if we can read the data - QFile file(QFileInfo(fileName).absoluteFilePath()); - file.open(QIODevice::ReadOnly); - if (file.isOpen()) { - // Read 16K in one go (QIODEVICE_BUFFERSIZE in qiodevice_p.h). - // This is much faster than seeking back and forth into QIODevice. - const QByteArray data = file.peek(16384); - - int magicAccuracy = 0; - MimeType candidateByData; - if (data.isEmpty()) { - magicAccuracy = 100; - candidateByData = mimeForName(types, QLatin1String("application/x-zerosize")); - } else { - candidateByData = d->provider()->bestMatchByMagic(data, types, &magicAccuracy); - if (!candidateByData.isValid()) { - if (isTextFile(data)) { - magicAccuracy = 5; - candidateByData = mimeForName(types, QLatin1String("text/plain")); - } - } - } - // Disambiguate conflicting extensions (if magic matching found something) - if (candidateByData.isValid() && magicAccuracy > 0) { - // "for glob_match in glob_matches:" - // "if glob_match is subclass or equal to sniffed_type, use glob_match" - const QString sniffedMime = candidateByData.name(); - foreach (const QString &m, candidatesByName) { - if (d->inherits(m, sniffedMime)) { - // We have magic + pattern pointing to this, so it's a pretty good match - return mimeForName(types, m); - } - } - return candidateByData; - } - } - - if (candidatesByName.count() > 1) { - candidatesByName.sort(); - return mimeForName(types, candidatesByName.first()); - } - return MimeType(); -} - /*! \fn MimeType MimeDatabase::mimeTypeForName(const QString &nameOrAlias) const; Returns a MIME type for \a nameOrAlias or an invalid one if none found. diff --git a/src/libs/utils/mimetypes/mimedatabase.h b/src/libs/utils/mimetypes/mimedatabase.h index f894933f769..246a82cec12 100644 --- a/src/libs/utils/mimetypes/mimedatabase.h +++ b/src/libs/utils/mimetypes/mimedatabase.h @@ -87,7 +87,6 @@ public: static void addMimeTypes(const QString &fileName); static QString allFiltersString(QString *allFilesFilter = 0); static QStringList allGlobPatterns(); - static MimeType bestMatch(const QString &fileName, const QList &types); static QMap > magicRulesForMimeType(const MimeType &mimeType); // priority -> rules static void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns); static void setMagicRulesForMimeType(const MimeType &mimeType, diff --git a/src/libs/utils/mimetypes/mimeprovider.cpp b/src/libs/utils/mimetypes/mimeprovider.cpp index a27cd11ea7b..45a081ad206 100644 --- a/src/libs/utils/mimetypes/mimeprovider.cpp +++ b/src/libs/utils/mimetypes/mimeprovider.cpp @@ -719,38 +719,6 @@ QStringList MimeXMLProvider::findByFileName(const QString &fileName, QString *fo return matchingMimeTypes; } -QStringList MimeXMLProvider::bestMatchByFileName(const QString &fileName, const QList &types) -{ - ensureLoaded(); - - // this is slow :( - // this would be much better if MimeType had references to their globs & magics - MimeAllGlobPatterns globs; - // fast patterns are fast (hash lookup), no need to reduce that set - globs.m_fastPatterns = m_mimeTypeGlobs.m_fastPatterns; - // fill highWeight and lowWeight glob lists - QSet names; - foreach (const MimeType &mt, types) - names.insert(mt.name()); - foreach (const MimeGlobPattern &pattern, m_mimeTypeGlobs.m_highWeightGlobs) { - if (names.contains(pattern.mimeType())) - globs.m_highWeightGlobs.append(pattern); - } - foreach (const MimeGlobPattern &pattern, m_mimeTypeGlobs.m_lowWeightGlobs) { - if (names.contains(pattern.mimeType())) - globs.m_lowWeightGlobs.append(pattern); - } - QString foundSuffix; - const QStringList matchingMimeTypes = globs.matchingGlobs(fileName, &foundSuffix); - // result can still contain types that are not in our list, because of the fast patterns - QStringList result; - foreach (const QString &match, matchingMimeTypes) { - if (names.contains(match)) - result.append(match); - } - return result; -} - MimeType MimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr) { ensureLoaded(); @@ -769,30 +737,6 @@ MimeType MimeXMLProvider::findByMagic(const QByteArray &data, int *accuracyPtr) return mimeTypeForName(candidate); } -MimeType MimeXMLProvider::bestMatchByMagic(const QByteArray &data, const QList &types, int *accuracyPtr) -{ - ensureLoaded(); - - QSet names; - foreach (const MimeType &mt, types) - names.insert(mt.name()); - - QString candidate; - - foreach (const MimeMagicRuleMatcher &matcher, m_magicMatchers) { - if (!names.contains(matcher.mimetype())) - continue; - if (matcher.matches(data)) { - const int priority = matcher.priority(); - if (priority > *accuracyPtr) { - *accuracyPtr = priority; - candidate = matcher.mimetype(); - } - } - } - return mimeTypeForName(candidate); -} - QMap > MimeXMLProvider::magicRulesForMimeType(const MimeType &mimeType) { QMap > result; diff --git a/src/libs/utils/mimetypes/mimeprovider_p.h b/src/libs/utils/mimetypes/mimeprovider_p.h index 9a375a018dd..eee3737d4da 100644 --- a/src/libs/utils/mimetypes/mimeprovider_p.h +++ b/src/libs/utils/mimetypes/mimeprovider_p.h @@ -75,8 +75,6 @@ public: virtual void loadGenericIcon(MimeTypePrivate &) {} // Qt Creator additions - virtual QStringList bestMatchByFileName(const QString &fileName, const QList &types) = 0; - virtual MimeType bestMatchByMagic(const QByteArray &data, const QList &types, int *accuracyPtr) = 0; virtual QMap > magicRulesForMimeType(const MimeType &mimeType) = 0; virtual void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns) = 0; virtual void setMagicRulesForMimeType(const MimeType &mimeType, const QMap > &rules) = 0; @@ -158,8 +156,6 @@ public: // Qt Creator additions void addFile(const QString &filePath); - QStringList bestMatchByFileName(const QString &fileName, const QList &types); - MimeType bestMatchByMagic(const QByteArray &data, const QList &types, int *accuracyPtr); QMap > magicRulesForMimeType(const MimeType &mimeType); void setGlobPatternsForMimeType(const MimeType &mimeType, const QStringList &patterns); void setMagicRulesForMimeType(const MimeType &mimeType, const QMap > &rules); diff --git a/src/plugins/cpptools/cppprojectfile.cpp b/src/plugins/cpptools/cppprojectfile.cpp index 56a035adc70..eceea5f350b 100644 --- a/src/plugins/cpptools/cppprojectfile.cpp +++ b/src/plugins/cpptools/cppprojectfile.cpp @@ -142,8 +142,9 @@ ProjectFileAdder::~ProjectFileAdder() bool ProjectFileAdder::maybeAdd(const QString &path) { - const Utils::MimeType mt = Utils::MimeDatabase::bestMatch(path, m_mimeTypes); - if (mt.isValid()) { + Utils::MimeDatabase mdb; + const Utils::MimeType mt = mdb.mimeTypeForFile(path); + if (m_mimeNameMapping.contains(mt.name())) { m_files << ProjectFile(path, m_mimeNameMapping.value(mt.name())); return true; } @@ -154,10 +155,8 @@ void ProjectFileAdder::addMapping(const char *mimeName, ProjectFile::Kind kind) { Utils::MimeDatabase mdb; Utils::MimeType mimeType = mdb.mimeTypeForName(QLatin1String(mimeName)); - if (mimeType.isValid()) { + if (mimeType.isValid()) m_mimeNameMapping.insert(mimeType.name(), kind); - m_mimeTypes.append(mimeType); - } } } // namespace Internal diff --git a/src/plugins/cpptools/cppprojectfile.h b/src/plugins/cpptools/cppprojectfile.h index c656b70e8b8..cf3b01fe8b5 100644 --- a/src/plugins/cpptools/cppprojectfile.h +++ b/src/plugins/cpptools/cppprojectfile.h @@ -88,7 +88,6 @@ private: QList &m_files; QHash m_mimeNameMapping; - QList m_mimeTypes; }; } // namespace Internal diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index a4f8b790531..b4ef92c6bef 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -81,14 +81,14 @@ ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfoForProject( Target *activeTarget = 0; if (project) { MimeDatabase mdb; - QList qmlTypes; - foreach (const MimeType &mimeType, mdb.allMimeTypes()) { - if (mimeType.matchesName(QLatin1String(Constants::QML_MIMETYPE)) - || mimeType.allAncestors().contains(QLatin1String(Constants::QML_MIMETYPE))) - qmlTypes.append(mimeType); - } + QSet qmlTypeNames; + qmlTypeNames << QLatin1String(Constants::QML_MIMETYPE) + << QLatin1String(Constants::QBS_MIMETYPE) + << QLatin1String(Constants::QMLPROJECT_MIMETYPE) + << QLatin1String(Constants::QMLTYPES_MIMETYPE) + << QLatin1String(Constants::QMLUI_MIMETYPE); foreach (const QString &filePath, project->files(Project::ExcludeGeneratedFiles)) { - if (mdb.bestMatch(filePath, qmlTypes).isValid()) + if (qmlTypeNames.contains(mdb.mimeTypeForFile(filePath).name())) projectInfo.sourceFiles << filePath; } activeTarget = project->activeTarget();