From 2d2f972bff73d522250bf0ebcd0708d344d37483 Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii Date: Wed, 31 Aug 2022 11:37:04 +0300 Subject: [PATCH] Fix loading xcursor themes with invalid Inherits field Xcursor loading can get stuck in an infinite recursion if index.theme file indicates that the theme inherits itself. In order to prevent that, keep track of the loaded so far themes and avoid loading already loaded themes. BUG: 457926 --- src/xcursortheme.cpp | 40 ++++++++++++++++++++++++++++------------ 1 file changed, 28 insertions(+), 12 deletions(-) diff --git a/src/xcursortheme.cpp b/src/xcursortheme.cpp index 5017deac2e..2421739679 100644 --- a/src/xcursortheme.cpp +++ b/src/xcursortheme.cpp @@ -12,7 +12,9 @@ #include #include +#include #include +#include #include namespace KWin @@ -157,22 +159,36 @@ static QStringList searchPaths() void KXcursorThemePrivate::load(const QString &themeName, int size, qreal devicePixelRatio) { const QStringList paths = searchPaths(); - QStringList inherits; - for (const QString &path : paths) { - const QDir dir(path + QLatin1Char('/') + themeName); - if (!dir.exists()) { + QStack stack; + QSet loaded; + + stack.push(themeName); + + while (!stack.isEmpty()) { + const QString themeName = stack.pop(); + if (loaded.contains(themeName)) { continue; } - loadCursors(dir.filePath(QStringLiteral("cursors")), size, devicePixelRatio); - if (inherits.isEmpty()) { - const KConfig config(dir.filePath(QStringLiteral("index.theme")), KConfig::NoGlobals); - inherits << KConfigGroup(&config, "Icon Theme").readEntry("Inherits", QStringList()); - } - } - for (const QString &inherit : inherits) { - load(inherit, size, devicePixelRatio); + QStringList inherits; + + for (const QString &path : paths) { + const QDir dir(path + QLatin1Char('/') + themeName); + if (!dir.exists()) { + continue; + } + loadCursors(dir.filePath(QStringLiteral("cursors")), size, devicePixelRatio); + if (inherits.isEmpty()) { + const KConfig config(dir.filePath(QStringLiteral("index.theme")), KConfig::NoGlobals); + inherits << KConfigGroup(&config, "Icon Theme").readEntry("Inherits", QStringList()); + } + } + + loaded.insert(themeName); + for (auto it = inherits.crbegin(); it != inherits.crend(); ++it) { + stack.push(*it); + } } }