From 6153c9ae025fa570174bb4a143df38fa2f46606b Mon Sep 17 00:00:00 2001
From: Tobias Fella <tobias.fella@kde.org>
Date: Wed, 8 Apr 2026 16:08:02 +0200
Subject: [PATCH] Remove control characters when quoting args Using these
 characters can lead to unexpected results.

---
 autotests/kshelltest.cpp     | 10 +++++++++-
 src/lib/util/kshell_unix.cpp | 15 ++++++++++-----
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/autotests/kshelltest.cpp b/autotests/kshelltest.cpp
index 09dbe3f0..5a4f4709 100644
--- a/autotests/kshelltest.cpp
+++ b/autotests/kshelltest.cpp
@@ -79,6 +79,14 @@ void KShellTest::quoteArg()
     QCOMPARE(KShell::quoteArg(QStringLiteral("a % space")), QStringLiteral("\"a %PERCENT_SIGN% space\""));
 #else
     QCOMPARE(KShell::quoteArg(QStringLiteral("a space")), QStringLiteral("'a space'"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("a\x01")), QStringLiteral("a"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("\x01")), QStringLiteral("''"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("a\x02")), QStringLiteral("a"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("a\x7f")), QStringLiteral("a"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("🫠")), QStringLiteral("🫠"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("👩‍👩‍👧‍👦")), QStringLiteral("👩‍👩‍👧‍👦"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("ひらがな")), QStringLiteral("ひらがな"));
+    QCOMPARE(KShell::quoteArg(QStringLiteral("ひらがな\x1")), QStringLiteral("ひらがな"));
 #endif
 }
 
@@ -124,7 +132,7 @@ void KShellTest::splitJoin()
     QCOMPARE(err, KShell::NoError);
 #else
     QCOMPARE(sj(QString::fromUtf8("\"~qU4rK\" 'text' 'jo'\"jo\" $'crap' $'\\\\\\'\\e\\x21' ha\\ lo \\a"), KShell::NoOptions, &err),
-             QString::fromUtf8("'~qU4rK' text jojo crap '\\'\\''\x1b!' 'ha lo' a"));
+             QString::fromUtf8("'~qU4rK' text jojo crap '\\'\\''!' 'ha lo' a"));
     QCOMPARE(err, KShell::NoError);
 
     QCOMPARE(sj(QStringLiteral("\"~qU4rK\" 'text'"), KShell::TildeExpand, &err), QStringLiteral("'~qU4rK' text"));
diff --git a/src/lib/util/kshell_unix.cpp b/src/lib/util/kshell_unix.cpp
index e87afc8c..61c0aad4 100644
--- a/src/lib/util/kshell_unix.cpp
+++ b/src/lib/util/kshell_unix.cpp
@@ -294,14 +294,19 @@ inline static bool isSpecial(QChar cUnicode)
 
 QString KShell::quoteArg(const QString &arg)
 {
-    if (arg.isEmpty()) {
+    auto quoted = arg;
+    quoted.removeIf([](const QChar &input) {
+        return input.category() == QChar::Other_Control;
+    });
+    if (quoted.isEmpty()) {
         return QStringLiteral("''");
     }
-    for (int i = 0; i < arg.length(); i++) {
-        if (isSpecial(arg.unicode()[i])) {
+
+    for (int i = 0; i < quoted.length(); i++) {
+        if (isSpecial(quoted.unicode()[i])) {
             QChar q(QLatin1Char('\''));
-            return q + QString(arg).replace(q, QLatin1String("'\\''")) + q;
+            return q + QString(quoted).replace(q, QLatin1String("'\\''")) + q;
         }
     }
-    return arg;
+    return quoted;
 }
-- 
GitLab

