summaryrefslogtreecommitdiffstats
path: root/source/kde/kde/patch/kate/c5d66f3b70ae4778d6162564309aee95f643e7c9.patch
blob: cc3f058d7563ee7930055327bfd8799a91c298d4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From c5d66f3b70ae4778d6162564309aee95f643e7c9 Mon Sep 17 00:00:00 2001
From: Christoph Cullmann <cullmann@kde.org>
Date: Thu, 20 Jan 2022 21:00:09 +0100
Subject: [PATCH] avoid that we execute LSP binaries from cwd

QProcess will just use current working directory as
fallback

that allows to execute un-wanted binaries by accident
---
 addons/lspclient/lspclientservermanager.cpp | 87 ++++++++++++---------
 1 file changed, 51 insertions(+), 36 deletions(-)

diff --git a/addons/lspclient/lspclientservermanager.cpp b/addons/lspclient/lspclientservermanager.cpp
index 24e3f275b..e78b4aa2d 100644
--- a/addons/lspclient/lspclientservermanager.cpp
+++ b/addons/lspclient/lspclientservermanager.cpp
@@ -707,52 +707,67 @@ private:
             }
 
             if (cmdline.length() > 0) {
+                // ensure we always only take the server executable from the PATH or user defined paths
+                // QProcess will take the executable even just from current working directory without this => BAD
+                auto cmd = QStandardPaths::findExecutable(cmdline[0]);
+
                 // optionally search in supplied path(s)
-                auto vpath = serverConfig.value(QStringLiteral("path")).toArray();
-                if (vpath.size() > 0) {
-                    auto cmd = QStandardPaths::findExecutable(cmdline[0]);
-                    if (cmd.isEmpty()) {
-                        // collect and expand in case home dir or other (environment) variable reference is used
-                        QStringList path;
-                        for (const auto &e : vpath) {
-                            auto p = e.toString();
-                            editor->expandText(p, view, p);
-                            path.push_back(p);
-                        }
-                        cmd = QStandardPaths::findExecutable(cmdline[0], path);
-                        if (!cmd.isEmpty()) {
-                            cmdline[0] = cmd;
-                        }
+                const auto vpath = serverConfig.value(QStringLiteral("path")).toArray();
+                if (cmd.isEmpty() && !vpath.isEmpty()) {
+                    // collect and expand in case home dir or other (environment) variable reference is used
+                    QStringList path;
+                    for (const auto &e : vpath) {
+                        auto p = e.toString();
+                        editor->expandText(p, view, p);
+                        path.push_back(p);
                     }
+                    cmd = QStandardPaths::findExecutable(cmdline[0], path);
                 }
-                // an empty list is always passed here (or null)
-                // the initial list is provided/updated using notification after start
-                // since that is what a server is more aware of
-                // and should support if it declares workspace folder capable
-                // (as opposed to the new initialization property)
-                LSPClientServer::FoldersType folders;
-                if (useWorkspace) {
-                    folders = QList<LSPWorkspaceFolder>();
-                }
-                server.reset(new LSPClientServer(cmdline, root, realLangId, serverConfig.value(QStringLiteral("initializationOptions")), folders));
-                connect(server.data(), &LSPClientServer::stateChanged, this, &self_type::onStateChanged, Qt::UniqueConnection);
-                if (!server->start()) {
-                    QString message = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' ')));
+
+                // we can only start the stuff if we did find the binary in the paths
+                if (!cmd.isEmpty()) {
+                    // use full path to avoid security issues
+                    cmdline[0] = cmd;
+
+                    // an empty list is always passed here (or null)
+                    // the initial list is provided/updated using notification after start
+                    // since that is what a server is more aware of
+                    // and should support if it declares workspace folder capable
+                    // (as opposed to the new initialization property)
+                    LSPClientServer::FoldersType folders;
+                    if (useWorkspace) {
+                        folders = QList<LSPWorkspaceFolder>();
+                    }
+                    server.reset(new LSPClientServer(cmdline, root, realLangId, serverConfig.value(QStringLiteral("initializationOptions")), folders));
+                    connect(server.data(), &LSPClientServer::stateChanged, this, &self_type::onStateChanged, Qt::UniqueConnection);
+                    if (!server->start()) {
+                        QString message = i18n("Failed to start server: %1", cmdline.join(QLatin1Char(' ')));
+                        const auto url = serverConfig.value(QStringLiteral("url")).toString();
+                        if (!url.isEmpty()) {
+                            message += QStringLiteral("\n") + i18n("Please check your PATH for the binary");
+                            message += QStringLiteral("\n") + i18n("See also %1 for installation or details", url);
+                        }
+                        showMessage(message, KTextEditor::Message::Warning);
+                    } else {
+                        showMessage(i18n("Started server %2: %1", cmdline.join(QLatin1Char(' ')), serverDescription(server.data())),
+                                    KTextEditor::Message::Positive);
+                        using namespace std::placeholders;
+                        server->connect(server.data(), &LSPClientServer::logMessage, this, std::bind(&self_type::onMessage, this, true, _1));
+                        server->connect(server.data(), &LSPClientServer::showMessage, this, std::bind(&self_type::onMessage, this, false, _1));
+                        server->connect(server.data(), &LSPClientServer::workDoneProgress, this, &self_type::onWorkDoneProgress);
+                        server->connect(server.data(), &LSPClientServer::workspaceFolders, this, &self_type::onWorkspaceFolders, Qt::UniqueConnection);
+                    }
+                } else {
+                    // we didn't find the server binary at all!
+                    QString message = i18n("Failed to find server binary: %1", cmdline[0]);
                     const auto url = serverConfig.value(QStringLiteral("url")).toString();
                     if (!url.isEmpty()) {
                         message += QStringLiteral("\n") + i18n("Please check your PATH for the binary");
                         message += QStringLiteral("\n") + i18n("See also %1 for installation or details", url);
                     }
                     showMessage(message, KTextEditor::Message::Warning);
-                } else {
-                    showMessage(i18n("Started server %2: %1", cmdline.join(QLatin1Char(' ')), serverDescription(server.data())),
-                                KTextEditor::Message::Positive);
-                    using namespace std::placeholders;
-                    server->connect(server.data(), &LSPClientServer::logMessage, this, std::bind(&self_type::onMessage, this, true, _1));
-                    server->connect(server.data(), &LSPClientServer::showMessage, this, std::bind(&self_type::onMessage, this, false, _1));
-                    server->connect(server.data(), &LSPClientServer::workDoneProgress, this, &self_type::onWorkDoneProgress);
-                    server->connect(server.data(), &LSPClientServer::workspaceFolders, this, &self_type::onWorkspaceFolders, Qt::UniqueConnection);
                 }
+
                 serverinfo.settings = serverConfig.value(QStringLiteral("settings"));
                 serverinfo.started = QTime::currentTime();
                 serverinfo.url = serverConfig.value(QStringLiteral("url")).toString();
-- 
GitLab