diff --git a/0001-QMimeDatabase-handle-buggy-type-definitions.patch b/0001-QMimeDatabase-handle-buggy-type-definitions.patch new file mode 100644 index 0000000..18db8b1 --- /dev/null +++ b/0001-QMimeDatabase-handle-buggy-type-definitions.patch @@ -0,0 +1,162 @@ +From 54656da9ace06caf4a0eeb1832989c0ab211a4a0 Mon Sep 17 00:00:00 2001 +From: Alex Henrie +Date: Wed, 15 Nov 2023 09:36:06 -0700 +Subject: QMimeDatabase: handle buggy type definitions with circular + inheritance + +This fixes an infinite loop reported by a user who had both the +definition of text/javascript from shared-mime-info 2.3 and the +definition of text/javascript from shared-mime-info 2.4 installed at the +same time. In 2.3, text/javascript is a subtype of +application/ecmascript, but in 2.4 application/ecmascript is a subtype +of text/javascript. Having both at the same time resulted in circular +inheritance. + +https://gitlab.freedesktop.org/xdg/shared-mime-info/-/merge_requests/258#note_2167707 + +[ChangeLog][QtCore][QMimeDatabase] Added code to detect and break +circular inheritance loops in the MIME data, which were causing infinite +loops + +Pick-to: 6.6 6.5 +Change-Id: Ic207b1593a49c7bb88e4fd810d8f88aa630087ce +Reviewed-by: Thiago Macieira +Reviewed-by: David Faure +--- + src/corelib/mimetypes/qmimedatabase.cpp | 9 +++++++-- + src/corelib/mimetypes/qmimetype.cpp | 7 +++++-- + .../mimetypes/qmimedatabase/circular-inheritance.xml | 13 +++++++++++++ + .../qmimedatabase/qmimedatabase-cache/CMakeLists.txt | 1 + + .../qmimedatabase/qmimedatabase-xml/CMakeLists.txt | 1 + + .../corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp | 8 ++++++++ + 6 files changed, 35 insertions(+), 4 deletions(-) + create mode 100644 tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml + +diff --git a/src/corelib/mimetypes/qmimedatabase.cpp b/src/corelib/mimetypes/qmimedatabase.cpp +index f06a434d55..eaeb079c97 100644 +--- a/src/corelib/mimetypes/qmimedatabase.cpp ++++ b/src/corelib/mimetypes/qmimedatabase.cpp +@@ -10,6 +10,7 @@ + #include "qmimeprovider_p.h" + #include "qmimetype_p.h" + ++#include + #include + + #include +@@ -503,6 +504,7 @@ QList QMimeDatabasePrivate::allMimeTypes() + bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) + { + const QString resolvedParent = resolveAlias(parent); ++ QDuplicateTracker seen; + std::stack toCheck; + toCheck.push(mime); + while (!toCheck.empty()) { +@@ -511,8 +513,11 @@ bool QMimeDatabasePrivate::inherits(const QString &mime, const QString &parent) + const QString mimeName = toCheck.top(); + toCheck.pop(); + const auto parentList = parents(mimeName); +- for (const QString &par : parentList) +- toCheck.push(resolveAlias(par)); ++ for (const QString &par : parentList) { ++ const QString resolvedPar = resolveAlias(par); ++ if (!seen.hasSeen(resolvedPar)) ++ toCheck.push(resolvedPar); ++ } + } + return false; + } +diff --git a/src/corelib/mimetypes/qmimetype.cpp b/src/corelib/mimetypes/qmimetype.cpp +index bed9e94364..ad3c484f30 100644 +--- a/src/corelib/mimetypes/qmimetype.cpp ++++ b/src/corelib/mimetypes/qmimetype.cpp +@@ -325,14 +325,17 @@ QStringList QMimeType::parentMimeTypes() const + static void collectParentMimeTypes(const QString &mime, QStringList &allParents) + { + const QStringList parents = QMimeDatabasePrivate::instance()->mimeParents(mime); ++ QStringList newParents; + for (const QString &parent : parents) { + // I would use QSet, but since order matters I better not +- if (!allParents.contains(parent)) ++ if (!allParents.contains(parent)) { + allParents.append(parent); ++ newParents.append(parent); ++ } + } + // We want a breadth-first search, so that the least-specific parent (octet-stream) is last + // This means iterating twice, unfortunately. +- for (const QString &parent : parents) ++ for (const QString &parent : newParents) + collectParentMimeTypes(parent, allParents); + } + +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml b/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml +new file mode 100644 +index 0000000000..466f039803 +--- /dev/null ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/circular-inheritance.xml +@@ -0,0 +1,13 @@ ++ ++ ++ ++ It's more accurate to say that ECMAScript is a subset of JavaScript ++ ++ ++ ++ ++ than to say that JavaScript is a subset of ECMAScript ++ ++ ++ ++ +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt +index 9a70666b07..a267640a50 100644 +--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-cache/CMakeLists.txt +@@ -31,5 +31,6 @@ qt_internal_add_test(tst_qmimedatabase-cache + #) + set(testdata_resource_files ++ "../circular-inheritance.xml" + "../invalid-magic1.xml" + "../invalid-magic2.xml" + "../invalid-magic3.xml" +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt +index 205d3c362b..729ac3933a 100644 +--- a/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/qmimedatabase-xml/CMakeLists.txt +@@ -31,5 +31,6 @@ qt_internal_add_test(tst_qmimedatabase-xml + #) + set(testdata_resource_files ++ "../circular-inheritance.xml" + "../invalid-magic1.xml" + "../invalid-magic2.xml" + "../invalid-magic3.xml" +diff --git a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +index 9bc3037c99..d7db4bb9bf 100644 +--- a/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp ++++ b/tests/auto/corelib/mimetypes/qmimedatabase/tst_qmimedatabase.cpp +@@ -38,6 +38,7 @@ + "invalid-magic2.xml", + "invalid-magic3.xml", + "magic-and-hierarchy.xml", ++ "circular-inheritance.xml", + 0 }; + + static const auto s_resourcePrefix = ":/qt-project.org/qmime/"_L1; +@@ -388,6 +389,13 @@ void tst_QMimeDatabase::inheritance() + const QMimeType mswordTemplate = db.mimeTypeForName(QString::fromLatin1("application/msword-template")); + QVERIFY(mswordTemplate.isValid()); + QVERIFY(mswordTemplate.inherits(QLatin1String("application/msword"))); ++ ++ // Check that buggy type definitions that have circular inheritance don't cause an infinite ++ // loop, especially when resolving a conflict between the file's name and its contents ++ const QMimeType ecmascript = db.mimeTypeForName(QString::fromLatin1("application/ecmascript")); ++ QVERIFY(ecmascript.allAncestors().contains("text/plain")); ++ const QMimeType javascript = db.mimeTypeForFileNameAndData("xml.js", ""); ++ QVERIFY(javascript.inherits(QString::fromLatin1("text/javascript"))); + } + + void tst_QMimeDatabase::aliases() +-- +cgit v1.2.3 + diff --git a/qt6-base.changes b/qt6-base.changes index f255eea..0eb47c0 100644 --- a/qt6-base.changes +++ b/qt6-base.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Mon Dec 4 19:11:49 UTC 2023 - Kacper Koniuszy + +- Add upstream patch for a bug in QMimeDatabase that causes some + applications to hang: + * 0001-QMimeDatabase-handle-buggy-type-definitions.patch + * https://code.qt.io/cgit/qt/qtbase.git/commit/?id=54656da9ace06caf4a0eeb1832989c0ab211a4a0 + ------------------------------------------------------------------- Mon Nov 27 14:00:05 UTC 2023 - Christophe Marin diff --git a/qt6-base.spec b/qt6-base.spec index 3078248..044501f 100644 --- a/qt6-base.spec +++ b/qt6-base.spec @@ -39,6 +39,7 @@ URL: https://www.qt.io Source: https://download.qt.io/official_releases/qt/%{short_version}/%{real_version}%{tar_suffix}/submodules/%{tar_name}-%{real_version}%{tar_suffix}.tar.xz Source99: qt6-base-rpmlintrc # Patches 0-100 are upstream patches # +Patch0: 0001-QMimeDatabase-handle-buggy-type-definitions.patch # Patches 100-200 are openSUSE and/or non-upstream(able) patches # Patch100: 0001-Tell-the-truth-about-private-API.patch # No need to pollute the library dir with object files, install them in the qt6 subfolder