QMimeDatabase: Fix MIME detection issues with magics in MIME hierarchies
Assume two MIME types A and B are registered, both with the same glob pattern, A being parent of B, A with some magic rule, and B with another magic rule. Given a file that matches the glob pattern and the magic rule of A, the resulting MIME type depended on the order of registration of A and B, because it would just check if some glob matching MIME type was also a subclass of the magic matching MIME type. The patch prefers the the MIME type that matches by magic if that matches by glob pattern as well (i.e. A in our example). The "recommended checking order" of the spec does handle that case. Task-number: QTBUG-44846 Change-Id: I2af43f6199faf9a42cd9c35d3a045441afbd6217 Reviewed-by: Eike Ziller <eike.ziller@qt.io> Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
fe9a37ac48
commit
67984b265a
@ -382,9 +382,12 @@ QMimeType QMimeDatabasePrivate::mimeTypeForFileNameAndData(const QString &fileNa
|
||||
|
||||
// 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();
|
||||
// If the sniffedMime matches a glob match, use it
|
||||
if (candidatesByName.m_matchingMimeTypes.contains(sniffedMime)) {
|
||||
*accuracyPtr = 100;
|
||||
return candidateByData;
|
||||
}
|
||||
for (const QString &m : qAsConst(candidatesByName.m_matchingMimeTypes)) {
|
||||
if (inherits(m, sniffedMime)) {
|
||||
// We have magic + pattern pointing to this, so it's a pretty good match
|
||||
|
@ -0,0 +1,3 @@
|
||||
<?foo>
|
||||
<blah>
|
||||
</blah>
|
@ -0,0 +1,21 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
|
||||
<!-- The real life example would be that this mime type is a sub class of application/xml
|
||||
which has a magic that matches <?xml .
|
||||
XML files with an early appearing qnx tag are detected as
|
||||
application/vnd.qnx.bar-descriptor. We want that XML files without the qnx tag to be
|
||||
identified as application/xml, independent of the order in which the two are registered. -->
|
||||
<mime-type type="application/vnd.qnx.bar-descriptor">
|
||||
<sub-class-of type="application/foo"/>
|
||||
<glob pattern="*.foo"/>
|
||||
<magic><!-- higher priority than the parent magic -->
|
||||
<match value="<qnx>" type="string" offset="0:200"/>
|
||||
</magic>
|
||||
</mime-type>
|
||||
<mime-type type="application/foo">
|
||||
<glob pattern="*.foo"/>
|
||||
<magic priority="40">
|
||||
<match value="<?foo" type="string" offset="0"/>
|
||||
</magic>
|
||||
</mime-type>
|
||||
</mime-info>
|
@ -0,0 +1,3 @@
|
||||
<?foo>
|
||||
<qnx>
|
||||
</qnx>
|
@ -7,5 +7,8 @@
|
||||
<file>invalid-magic1.xml</file>
|
||||
<file>invalid-magic2.xml</file>
|
||||
<file>invalid-magic3.xml</file>
|
||||
<file>magic-and-hierarchy.xml</file>
|
||||
<file>magic-and-hierarchy.foo</file>
|
||||
<file>magic-and-hierarchy2.foo</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@ -52,6 +52,7 @@ static const char *const additionalMimeFiles[] = {
|
||||
"invalid-magic1.xml",
|
||||
"invalid-magic2.xml",
|
||||
"invalid-magic3.xml",
|
||||
"magic-and-hierarchy.xml",
|
||||
0
|
||||
};
|
||||
|
||||
@ -985,6 +986,12 @@ void tst_QMimeDatabase::installNewGlobalMimeType()
|
||||
qDebug() << objcsrc.globPatterns();
|
||||
}
|
||||
|
||||
const QString fooTestFile = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy.foo");
|
||||
QCOMPARE(db.mimeTypeForFile(fooTestFile).name(), QString::fromLatin1("application/foo"));
|
||||
|
||||
const QString fooTestFile2 = QLatin1String(RESOURCE_PREFIX "magic-and-hierarchy2.foo");
|
||||
QCOMPARE(db.mimeTypeForFile(fooTestFile2).name(), QString::fromLatin1("application/vnd.qnx.bar-descriptor"));
|
||||
|
||||
// Now test removing the mimetype definitions again
|
||||
for (int i = 0; i < m_additionalMimeFileNames.size(); ++i)
|
||||
QFile::remove(destDir + m_additionalMimeFileNames.at(i));
|
||||
|
Loading…
Reference in New Issue
Block a user