summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Faure <david.faure@kdab.com>2020-03-26 11:09:24 +0200
committerDavid Faure <david.faure@kdab.com>2020-06-01 13:36:05 +0200
commit4f1ebf666e36020c501e6d3b20d70320b45ab2ec (patch)
tree2993a066475042a3bc4abf2026dde4ac85d99e55
parentb0294bb1c74ae3f5aabb873435788200da988908 (diff)
QMimeType::suffixForFileName shouldn't lowercase the file suffix
It was returning a lowercased suffix because it was extracting it from the pattern (*.txt) rather than from the filename ("README.TXT"). This broke expectations on the application side, since this method is documented to return a suffix from the given filename. Ref: https://bugs.kde.org/show_bug.cgi?id=402388 Change-Id: I7dae13db31280249d3f592fa9592c4067804e22d Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r--src/corelib/mimetypes/qmimedatabase.cpp3
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern.cpp26
-rw-r--r--src/corelib/mimetypes/qmimeglobpattern_p.h12
-rw-r--r--src/corelib/mimetypes/qmimeprovider.cpp2
-rw-r--r--tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp6
5 files changed, 33 insertions, 16 deletions
diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp
index d65f1bdebd..974ca36a40 100644
--- a/src/corelib/mimetypes/qmimedatabase.cpp
+++ b/src/corelib/mimetypes/qmimedatabase.cpp
@@ -638,7 +638,8 @@ QList<QMimeType> QMimeDatabase::mimeTypesForFileName(const QString &fileName) co
QString QMimeDatabase::suffixForFileName(const QString &fileName) const
{
QMutexLocker locker(&d->mutex);
- return d->findByFileName(QFileInfo(fileName).fileName()).m_foundSuffix;
+ const int suffixLength = d->findByFileName(QFileInfo(fileName).fileName()).m_knownSuffixLength;
+ return fileName.right(suffixLength);
}
/*!
diff --git a/src/corelib/mimetypes/qmimeglobpattern.cpp b/src/corelib/mimetypes/qmimeglobpattern.cpp
index 6d2a1f5425..9971913f9d 100644
--- a/src/corelib/mimetypes/qmimeglobpattern.cpp
+++ b/src/corelib/mimetypes/qmimeglobpattern.cpp
@@ -56,7 +56,7 @@ QT_BEGIN_NAMESPACE
Handles glob weights, and preferring longer matches over shorter matches.
*/
-void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern)
+void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const QString &pattern, int knownSuffixLength)
{
if (m_allMatchingMimeTypes.contains(mimeType))
return;
@@ -84,8 +84,7 @@ void QMimeGlobMatchResult::addMatch(const QString &mimeType, int weight, const Q
if (!m_matchingMimeTypes.contains(mimeType)) {
m_matchingMimeTypes.append(mimeType);
m_allMatchingMimeTypes.append(mimeType);
- if (pattern.startsWith(QLatin1String("*.")))
- m_foundSuffix = pattern.mid(2);
+ m_knownSuffixLength = knownSuffixLength;
}
}
@@ -152,6 +151,18 @@ bool QMimeGlobPattern::matchFileName(const QString &inputFilename) const
#endif
}
+static bool isSimplePattern(const QString &pattern)
+{
+ // starts with "*.", has no other '*'
+ return pattern.lastIndexOf(QLatin1Char('*')) == 0
+ && pattern.length() > 1
+ && pattern.at(1) == QLatin1Char('.') // (other dots are OK, like *.tar.bz2)
+ // and contains no other special character
+ && !pattern.contains(QLatin1Char('?'))
+ && !pattern.contains(QLatin1Char('['))
+ ;
+}
+
static bool isFastPattern(const QString &pattern)
{
// starts with "*.", has no other '*' and no other '.'
@@ -205,8 +216,11 @@ void QMimeGlobPatternList::match(QMimeGlobMatchResult &result,
const QMimeGlobPatternList::const_iterator endIt = this->constEnd();
for (; it != endIt; ++it) {
const QMimeGlobPattern &glob = *it;
- if (glob.matchFileName(fileName))
- result.addMatch(glob.mimeType(), glob.weight(), glob.pattern());
+ if (glob.matchFileName(fileName)) {
+ const QString pattern = glob.pattern();
+ const int suffixLen = isSimplePattern(pattern) ? pattern.length() - 2 : 0;
+ result.addMatch(glob.mimeType(), glob.weight(), pattern, suffixLen);
+ }
}
}
@@ -226,7 +240,7 @@ void QMimeAllGlobPatterns::matchingGlobs(const QString &fileName, QMimeGlobMatch
const QStringList matchingMimeTypes = m_fastPatterns.value(simpleExtension);
const QString simplePattern = QLatin1String("*.") + simpleExtension;
for (const QString &mime : matchingMimeTypes)
- result.addMatch(mime, 50, simplePattern);
+ result.addMatch(mime, 50, simplePattern, simpleExtension.size());
// Can't return yet; *.tar.bz2 has to win over *.bz2, so we need the low-weight mimetypes anyway,
// at least those with weight 50.
}
diff --git a/src/corelib/mimetypes/qmimeglobpattern_p.h b/src/corelib/mimetypes/qmimeglobpattern_p.h
index cf27d6ab30..49f145e8db 100644
--- a/src/corelib/mimetypes/qmimeglobpattern_p.h
+++ b/src/corelib/mimetypes/qmimeglobpattern_p.h
@@ -62,17 +62,13 @@ QT_BEGIN_NAMESPACE
struct QMimeGlobMatchResult
{
- QMimeGlobMatchResult()
- : m_weight(0), m_matchingPatternLength(0)
- {}
-
- void addMatch(const QString &mimeType, int weight, const QString &pattern);
+ void addMatch(const QString &mimeType, int weight, const QString &pattern, int knownSuffixLength = 0);
QStringList m_matchingMimeTypes; // only those with highest weight
QStringList m_allMatchingMimeTypes;
- int m_weight;
- int m_matchingPatternLength;
- QString m_foundSuffix;
+ int m_weight = 0;
+ int m_matchingPatternLength = 0;
+ int m_knownSuffixLength = 0;
};
class QMimeGlobPattern
diff --git a/src/corelib/mimetypes/qmimeprovider.cpp b/src/corelib/mimetypes/qmimeprovider.cpp
index 83574a40f0..e8e81e65ab 100644
--- a/src/corelib/mimetypes/qmimeprovider.cpp
+++ b/src/corelib/mimetypes/qmimeprovider.cpp
@@ -306,7 +306,7 @@ bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result, QMimeBin
const bool caseSensitive = flagsAndWeight & 0x100;
if (caseSensitiveCheck || !caseSensitive) {
result.addMatch(QLatin1String(mimeType), weight,
- QLatin1Char('*') + fileName.midRef(charPos + 1));
+ QLatin1Char('*') + fileName.midRef(charPos + 1), fileName.size() - charPos - 2);
success = true;
}
}
diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
index 3c6da506e2..c214c75d52 100644
--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
+++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp
@@ -667,6 +667,9 @@ void tst_QMimeDatabase::knownSuffix()
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bz2")), QString::fromLatin1("bz2"));
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.bar.bz2")), QString::fromLatin1("bz2"));
QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.tar.bz2")), QString::fromLatin1("tar.bz2"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.TAR")), QString::fromLatin1("TAR")); // preserve case
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.flatpakrepo")), QString::fromLatin1("flatpakrepo"));
+ QCOMPARE(db.suffixForFileName(QString::fromLatin1("foo.anim2")), QString()); // the glob is anim[0-9], no way to extract the extension without expensive regexp capturing
}
void tst_QMimeDatabase::symlinkToFifo() // QTBUG-48529
@@ -784,6 +787,9 @@ void tst_QMimeDatabase::findByFileName()
// Test QFileInfo overload
const QMimeType mimeForFileInfo = database.mimeTypeForFile(QFileInfo(filePath), QMimeDatabase::MatchExtension);
QCOMPARE(mimeForFileInfo.name(), resultMimeTypeName);
+
+ const QString suffix = database.suffixForFileName(filePath);
+ QVERIFY2(filePath.endsWith(suffix), qPrintable(filePath + " does not end with " + suffix));
}
void tst_QMimeDatabase::findByData_data()