QMimeDatabase: fix detection of pattern conflict in different prefixes
Installing a second mimetype with *.txt as glob had a different effect depending on whether it was installed into the same prefix or a different prefix as the one where text/plain is installed. Change-Id: I7f54b8efe22f620eb57257745c48fe5402c87626 Reviewed-by: Thiago Macieira <thiago.macieira@intel.com> (cherry picked from commit 1b39e61a775d70ee96287e9f0e418cb5741e6638) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
941b2de2ee
commit
30d416c67d
@ -213,22 +213,25 @@ void QMimeBinaryProvider::addFileNameMatches(const QString &fileName, QMimeGlobM
|
|||||||
return;
|
return;
|
||||||
Q_ASSERT(m_cacheFile);
|
Q_ASSERT(m_cacheFile);
|
||||||
const QString lowerFileName = fileName.toLower();
|
const QString lowerFileName = fileName.toLower();
|
||||||
|
int numMatches = 0;
|
||||||
// Check literals (e.g. "Makefile")
|
// Check literals (e.g. "Makefile")
|
||||||
matchGlobList(result, m_cacheFile.get(), m_cacheFile->getUint32(PosLiteralListOffset),
|
numMatches = matchGlobList(result, m_cacheFile.get(),
|
||||||
fileName);
|
m_cacheFile->getUint32(PosLiteralListOffset), fileName);
|
||||||
// Check the very common *.txt cases with the suffix tree
|
// 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 reverseSuffixTreeOffset = m_cacheFile->getUint32(PosReverseSuffixTreeOffset);
|
||||||
const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
|
const int numRoots = m_cacheFile->getUint32(reverseSuffixTreeOffset);
|
||||||
const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
|
const int firstRootOffset = m_cacheFile->getUint32(reverseSuffixTreeOffset + 4);
|
||||||
matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, lowerFileName,
|
if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, lowerFileName,
|
||||||
lowerFileName.size() - 1, false);
|
lowerFileName.size() - 1, false)) {
|
||||||
if (result.m_matchingMimeTypes.isEmpty())
|
++numMatches;
|
||||||
matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, fileName,
|
} else if (matchSuffixTree(result, m_cacheFile.get(), numRoots, firstRootOffset, fileName,
|
||||||
fileName.size() - 1, true);
|
fileName.size() - 1, true)) {
|
||||||
|
++numMatches;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check complex globs (e.g. "callgrind.out[0-9]*" or "README*")
|
// 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),
|
matchGlobList(result, m_cacheFile.get(), m_cacheFile->getUint32(PosGlobListOffset),
|
||||||
fileName);
|
fileName);
|
||||||
}
|
}
|
||||||
@ -244,8 +247,10 @@ void QMimeBinaryProvider::excludeMimeTypeGlobs(const QStringList &toExclude)
|
|||||||
appendIfNew(m_mimeTypesWithExcludedGlobs, mt);
|
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);
|
const int numGlobs = cacheFile->getUint32(off);
|
||||||
//qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset;
|
//qDebug() << "Loading" << numGlobs << "globs from" << cacheFile->file.fileName() << "at offset" << cacheFile->globListOffset;
|
||||||
for (int i = 0; i < numGlobs; ++i) {
|
for (int i = 0; i < numGlobs; ++i) {
|
||||||
@ -263,9 +268,12 @@ void QMimeBinaryProvider::matchGlobList(QMimeGlobMatchResult &result, CacheFile
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
|
QMimeGlobPattern glob(pattern, QString() /*unused*/, weight, qtCaseSensitive);
|
||||||
if (glob.matchFileName(fileName))
|
if (glob.matchFileName(fileName)) {
|
||||||
result.addMatch(QLatin1StringView(mimeType), weight, pattern);
|
result.addMatch(QLatin1StringView(mimeType), weight, pattern);
|
||||||
|
++numMatches;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return numMatches;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result,
|
bool QMimeBinaryProvider::matchSuffixTree(QMimeGlobMatchResult &result,
|
||||||
|
@ -111,7 +111,8 @@ public:
|
|||||||
private:
|
private:
|
||||||
struct CacheFile;
|
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,
|
bool matchSuffixTree(QMimeGlobMatchResult &result, CacheFile *cacheFile, int numEntries,
|
||||||
int firstOffset, const QString &fileName, qsizetype charPos,
|
int firstOffset, const QString &fileName, qsizetype charPos,
|
||||||
bool caseSensitiveCheck);
|
bool caseSensitiveCheck);
|
||||||
|
@ -32,6 +32,7 @@ set(testdata_resource_files
|
|||||||
"../qml-again.xml"
|
"../qml-again.xml"
|
||||||
"../test.qml"
|
"../test.qml"
|
||||||
"../text-x-objcsrc.xml"
|
"../text-x-objcsrc.xml"
|
||||||
|
"../text-plain-subclass.xml"
|
||||||
"../yast2-metapackage-handler-mimetypes.xml"
|
"../yast2-metapackage-handler-mimetypes.xml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -32,6 +32,7 @@ set(testdata_resource_files
|
|||||||
"../qml-again.xml"
|
"../qml-again.xml"
|
||||||
"../test.qml"
|
"../test.qml"
|
||||||
"../text-x-objcsrc.xml"
|
"../text-x-objcsrc.xml"
|
||||||
|
"../text-plain-subclass.xml"
|
||||||
"../yast2-metapackage-handler-mimetypes.xml"
|
"../yast2-metapackage-handler-mimetypes.xml"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
|
||||||
|
<mime-type type="text/x-microdvd">
|
||||||
|
<comment>MicroDVD subtitles</comment>
|
||||||
|
<sub-class-of type="text/plain"/>
|
||||||
|
<magic priority="50">
|
||||||
|
<match type="string" value="{1}" offset="0"/>
|
||||||
|
<match type="string" value="{0}" offset="0"/>
|
||||||
|
<match type="string" value="}{" offset="0:6"/>
|
||||||
|
</magic>
|
||||||
|
<generic-icon name="text-x-generic"/>
|
||||||
|
<glob pattern="*.sub"/>
|
||||||
|
<glob pattern="*.txt"/>
|
||||||
|
</mime-type>
|
||||||
|
</mime-info>
|
@ -30,16 +30,15 @@
|
|||||||
|
|
||||||
using namespace Qt::StringLiterals;
|
using namespace Qt::StringLiterals;
|
||||||
|
|
||||||
static const char *const additionalMimeFiles[] = {
|
static const char *const additionalMimeFiles[] = { "yast2-metapackage-handler-mimetypes.xml",
|
||||||
"yast2-metapackage-handler-mimetypes.xml",
|
"qml-again.xml",
|
||||||
"qml-again.xml",
|
"text-x-objcsrc.xml",
|
||||||
"text-x-objcsrc.xml",
|
"text-plain-subclass.xml",
|
||||||
"invalid-magic1.xml",
|
"invalid-magic1.xml",
|
||||||
"invalid-magic2.xml",
|
"invalid-magic2.xml",
|
||||||
"invalid-magic3.xml",
|
"invalid-magic3.xml",
|
||||||
"magic-and-hierarchy.xml",
|
"magic-and-hierarchy.xml",
|
||||||
0
|
0 };
|
||||||
};
|
|
||||||
|
|
||||||
static const auto s_resourcePrefix = ":/qt-project.org/qmime/"_L1;
|
static const auto s_resourcePrefix = ":/qt-project.org/qmime/"_L1;
|
||||||
static const auto s_inodeMimetype = "inode/directory"_L1;
|
static const auto s_inodeMimetype = "inode/directory"_L1;
|
||||||
@ -1196,6 +1195,8 @@ void tst_QMimeDatabase::installNewLocalMimeType()
|
|||||||
QVERIFY(objcsrc.isValid());
|
QVERIFY(objcsrc.isValid());
|
||||||
QCOMPARE(objcsrc.globPatterns(), QStringList());
|
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").
|
// Test that a double-definition of a mimetype doesn't lead to sniffing ("conflicting globs").
|
||||||
const QString qmlTestFile = s_resourcePrefix + "test.qml"_L1;
|
const QString qmlTestFile = s_resourcePrefix + "test.qml"_L1;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user