-
Bug
-
Resolution: Fixed
-
P1: Critical
-
6.3, 6.6.0
-
None
-
-
4e9944e6c (dev), 705118a55 (6.6)
On linux it's common to have mime types defined in xml files that ship with
the system in /usr/share/mime/ and to have user installed ones in
~/.local/share/mime/. On Qt5, if a mimetype was specified in multiple
locations, QMimeDatabase would combine the glob patterns and suffixes from
both locations. On Qt6 it no longer does.
Here is a downstream report where this affects the file picker in QtWebEngine: https://github.com/qutebrowser/qutebrowser/issues/7866
I've tested all the Qt6 builds I have lying around (6.2.2, 6.3.0, 6.4.2, 6.5.2 and 6.6 (a local build from May, sha=b4e7e6cfa724ad)) and it looks like this regression was introduced some time between 6.2.2 and 6.3.0.
Here is a reproducer based off of an observed installation (mine!):
# Create two directories to serve as mime search paths.
# `a` corresponds to the `~/local/share/mime/` and `b` to `/usr/share/mime/`.
mkdir -p {a,b}/mime/packages/
# Write an XML file installed by a user application (wine)
cat > a/mime/packages/x-wine-extension-jfif.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="image/jpeg">
<glob pattern="*.jfif"/>
<comment>JPEG Image</comment>
</mime-type>
</mime-info>
EOF
# And the part of the system file with the same mime type
cat > b/mime/packages/freedesktop.org.xml <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
<mime-type type="image/jpeg">
<comment>JPEG image</comment>
<acronym>JPEG</acronym>
<expanded-acronym>Joint Photographic Experts Group</expanded-acronym>
<magic>
<match type="string" value="\377\330\377" offset="0"/>
<match type="big16" value="0xffd8" offset="0"/>
</magic>
<glob pattern="*.jpg"/>
<glob pattern="*.jpeg"/>
<glob pattern="*.jpe"/>
<alias type="image/pjpeg"/>
</mime-type>
</mime-info>
EOF
# Create a mime database in each directory
for d in a b; do update-mime-database $d/mime/ ;done
# Write a simple test applications using `QMimeType.globPatterns()`
# (`.suffixes()` has the same behaviour.)
cat > main.cpp <<EOF
#include <iostream>
#include <QMimeDatabase>
int main(int argc, char *argv[])
{
QMimeDatabase db;
for (auto p : db.mimeTypeForFile("foo.jpg").globPatterns()) {
std::cout << p.toStdString() << std::endl;
}
return 0;
}
EOF
g++ -o main-qt5 main.cpp `pkgconf --libs --cflags Qt5Core` -fPIC
g++ -o main-qt6 main.cpp `pkgconf --libs --cflags Qt6Core` -fPIC
# And run them
# XDG_DATA_DIRS is set to the directories created above, in a specific order.
# XDG_DATA_HOME is set to a non-existent directory to stop it from looking in
# your real home dir.
printf "\nFound by Qt5:\n" && XDG_DATA_DIRS="$PWD/a:$PWD/b" XDG_DATA_HOME='/tmp/nope' ./main-qt5
printf "\nFound by Qt6:\n" && XDG_DATA_DIRS="$PWD/a:$PWD/b" XDG_DATA_HOME='/tmp/nope' ./main-qt6
This should print out:
Found by Qt5: *.jpg *.jpeg *.jpe *.jfif Found by Qt6: *.jfif
Note that, in the cpp application, I'm looking up the mime type using a suffix
that is only specified in the system location, but when I list the glob patterns it's only
listing the one from the user location.
Switching the order of the paths in XDG_DATA_DIRS yields:
Found by Qt5: *.jfif *.jpg *.jpeg *.jpe Found by Qt6: *.jpg *.jpeg *.jpe
Again, it's only listing the glob patterns from the first location.
| For Gerrit Dashboard: QTBUG-116905 | ||||||
|---|---|---|---|---|---|---|
| # | Subject | Branch | Project | Status | CR | V |
| 503173,6 | QMimeDatabase: collect glob patterns from all locations | dev | qt/qtbase | Status: MERGED | +2 | 0 |
| 523541,2 | QMimeDatabase: collect glob patterns from all locations | 6.6 | qt/qtbase | Status: MERGED | +2 | 0 |