Commit bb573b83 authored by Kai Uwe Broulik's avatar Kai Uwe Broulik 🍇
Browse files

[Task Manager] Remove strict URL handling

The code tried hard to ignore garbage URLs, as Qt is quite lenient, e.g. QUrl("Garbage Url") is still valid.
There is no way to change the strictness of a QUrl after creation,
so the code would enforce it by doing QUrl strictUrl(inputUrl.toString(), QUrl::StrictMode).
However, toString() defaults to PrettyDecoded which avoids percent-encoding and keeps spaces
in tact which is not a valid thing to have in a strict URL.
Effectively, we want to ensure a URL is either a valid path to a local file,
or one of the special applications (for menu ids), or preferred for preferred applications, like web browser,

BUG: 385727
FIXED-IN: 5.18.0

Differential Revision:
parent 66940389
......@@ -36,6 +36,7 @@ class LauncherTasksModelTest : public QObject
void shouldRoundTripLauncherUrlList();
void shouldIgnoreInvalidUrls();
void shouldAcceptSpaces();
void shouldRejectDuplicates();
void shouldAddRemoveLauncher();
void shouldReturnValidLauncherPositions();
......@@ -91,6 +92,25 @@ void LauncherTasksModelTest::shouldIgnoreInvalidUrls()
QCOMPARE(m.launcherList(), QStringList());
void LauncherTasksModelTest::shouldAcceptSpaces()
LauncherTasksModel m;
const QStringList urlStrings{
QLatin1String("applications:App with spaces.desktop")
QSignalSpy launcherListChangedSpy(&m, &LauncherTasksModel::launcherListChanged);
const bool added = m.requestAddLauncher(QUrl(;
QCOMPARE(launcherListChangedSpy.count(), 1);
QCOMPARE(m.launcherList(), QStringList() <<;
void LauncherTasksModelTest::shouldRejectDuplicates()
LauncherTasksModel m;
......@@ -143,15 +143,13 @@ AppData LauncherTasksModel::Private::appData(const QUrl &url)
bool LauncherTasksModel::Private::requestAddLauncherToActivities(const QUrl &_url, const QStringList &_activities)
// isValid() for the passed-in URL might return true if it was
// constructed in TolerantMode, but we want to reject invalid URLs.
QUrl url(_url.toString(), QUrl::StrictMode);
const auto activities = ActivitiesSet::fromList(_activities);
if (url.isEmpty() || !url.isValid()) {
QUrl url(_url);
if (!isValidLauncherUrl(url)) {
return false;
const auto activities = ActivitiesSet::fromList(_activities);
if (url.isLocalFile() && KDesktopFile::isDesktopFile(url.toLocalFile())) {
KDesktopFile f(url.toLocalFile());
......@@ -409,7 +407,9 @@ void LauncherTasksModel::setLauncherList(const QStringList &serializedLaunchers)
auto activities = ActivitiesSet::fromList(_activities);
// Is url is not valid, ignore it
if (!url.isValid()) continue;
if (!isValidLauncherUrl(url)) {
// If we have a null uuid, it means we are on all activities
// and we should contain only the null uuid
......@@ -29,10 +29,25 @@ namespace TaskManager {
#define NULL_UUID "00000000-0000-0000-0000-000000000000"
inline static bool isValidLauncherUrl(const QUrl &url)
if (url.isEmpty() || !url.isValid()) {
return false;
if (!url.isLocalFile()
&& url.scheme() != QLatin1String("applications")
&& url.scheme() != QLatin1String("preferred")) {
return false;
return true;
inline static std::pair<QUrl, QStringList> deserializeLauncher(const QString &serializedLauncher)
QStringList activities;
QUrl url(serializedLauncher, QUrl::StrictMode);
QUrl url(serializedLauncher);
// The storage format is: [list of activity ids]\nURL
// The activity IDs list can not be empty, it at least needs
......@@ -47,7 +62,7 @@ inline static std::pair<QUrl, QStringList> deserializeLauncher(const QString &se
activities = serializedLauncher.mid(1, activitiesBlockEnd - 1).split(",", QString::SkipEmptyParts);
if (!activities.isEmpty()) {
url = QUrl(serializedLauncher.mid(activitiesBlockEnd + 2), QUrl::StrictMode);
url = QUrl(serializedLauncher.mid(activitiesBlockEnd + 2));
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment