Gentoo Archives: gentoo-commits

From: Andreas Sturmlechner <asturm@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: kde-frameworks/kio/files/, kde-frameworks/kio/
Date: Tue, 29 Sep 2020 12:49:36
Message-Id: 1601383603.79bc863dc74675a14f4818e979cab9e62557c369.asturm@gentoo
1 commit: 79bc863dc74675a14f4818e979cab9e62557c369
2 Author: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
3 AuthorDate: Mon Sep 28 22:41:56 2020 +0000
4 Commit: Andreas Sturmlechner <asturm <AT> gentoo <DOT> org>
5 CommitDate: Tue Sep 29 12:46:43 2020 +0000
6 URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=79bc863d
7
8 kde-frameworks/kio: OpenUrlJob: handle all text scripts consistently
9
10 Upstream commit fdd7c47c85d5d6dbf21e05e7a0d6afcf383f1d24
11
12 KDE-Bug: https://bugs.kde.org/show_bug.cgi?id=425829
13 Package-Manager: Portage-3.0.8, Repoman-3.0.1
14 Signed-off-by: Andreas Sturmlechner <asturm <AT> gentoo.org>
15
16 ...o-5.74.1-handle-shell-scripts-consistenty.patch | 310 +++++++++++++++++++++
17 kde-frameworks/kio/kio-5.74.1-r1.ebuild | 5 +-
18 2 files changed, 314 insertions(+), 1 deletion(-)
19
20 diff --git a/kde-frameworks/kio/files/kio-5.74.1-handle-shell-scripts-consistenty.patch b/kde-frameworks/kio/files/kio-5.74.1-handle-shell-scripts-consistenty.patch
21 new file mode 100644
22 index 00000000000..f5e17f338fd
23 --- /dev/null
24 +++ b/kde-frameworks/kio/files/kio-5.74.1-handle-shell-scripts-consistenty.patch
25 @@ -0,0 +1,310 @@
26 +From fdd7c47c85d5d6dbf21e05e7a0d6afcf383f1d24 Mon Sep 17 00:00:00 2001
27 +From: Ahmad Samir <a.samirh78@×××××.com>
28 +Date: Tue, 15 Sep 2020 20:06:49 +0200
29 +Subject: [PATCH] OpenUrlJob: handle all text scripts consistently
30 +
31 +Previously we only handled application/x-shellscript, but there are other
32 +scripts; a script is technically a file that inherits both text/plain and
33 +application/x-executable, e.g. .sh, .csh, .py, perl scripts ...etc. Treat
34 +all those mime types the way we handled shell scripts:
35 + - if it's not a local url, or isn't executable we open it in the preferred
36 + text editor
37 + - if it's executable either show the OpenOrExecute dialog or execute
38 + directly depending on how the job is configured
39 +
40 +The mimetype world is a confusing one:
41 + - Executables, this includes .exe files (MS Windows); and "application/x-executable"
42 + and "application/x-sharedlib", this depends on various parameters (e.g.
43 + stripped executables are x-sharedlib, the same executable if not stripped
44 + is x-executable...)
45 + - Scripts: shell, python, perl... etc scripts, which are text files that
46 + can be executed or opened as text.
47 +
48 +Adjust the unit test.
49 +
50 +BUG: 425829
51 +BUG: 425177
52 +FIXED-IN: 5.75
53 +---
54 + autotests/openurljobtest.cpp | 56 +++++++++++++++++++++++--------
55 + autotests/openurljobtest.h | 2 ++
56 + src/gui/openurljob.cpp | 65 ++++++++++++++++++++++--------------
57 + 3 files changed, 85 insertions(+), 38 deletions(-)
58 +
59 +diff --git a/autotests/openurljobtest.cpp b/autotests/openurljobtest.cpp
60 +index 2f2ef8ad..ed2211a8 100644
61 +--- a/autotests/openurljobtest.cpp
62 ++++ b/autotests/openurljobtest.cpp
63 +@@ -103,14 +103,13 @@ void OpenUrlJobTest::initTestCase()
64 + KConfigGroup grp = mimeAppsCfg.group("Default Applications");
65 + grp.writeEntry("text/plain", s_tempServiceName);
66 + grp.writeEntry("text/html", s_tempServiceName);
67 +- grp.writeEntry("application/x-shellscript", s_tempServiceName);
68 + grp.sync();
69 +
70 +- for (const char *mimeType : {"text/plain", "application/x-shellscript"}) {
71 +- KService::Ptr preferredTextEditor = KApplicationTrader::preferredService(QString::fromLatin1(mimeType));
72 +- QVERIFY(preferredTextEditor);
73 +- QCOMPARE(preferredTextEditor->entryPath(), m_fakeService);
74 +- }
75 ++
76 ++ // "text/plain" encompasses all scripts (shell, python, perl)
77 ++ KService::Ptr preferredTextEditor = KApplicationTrader::preferredService(QStringLiteral("text/plain"));
78 ++ QVERIFY(preferredTextEditor);
79 ++ QCOMPARE(preferredTextEditor->entryPath(), m_fakeService);
80 +
81 + // As used for preferredService
82 + QVERIFY(KService::serviceByDesktopName("openurljobtest_service"));
83 +@@ -230,17 +229,38 @@ void OpenUrlJobTest::invalidUrl()
84 + QCOMPARE(job2->errorString(), QStringLiteral("Malformed URL\n/pathonly"));
85 + }
86 +
87 ++void OpenUrlJobTest::refuseRunningNativeExecutables_data()
88 ++{
89 ++ QTest::addColumn<QString>("mimeType");
90 ++
91 ++ // Executables under e.g. /usr/bin/ can be either of these two mimetypes
92 ++ // see https://gitlab.freedesktop.org/xdg/shared-mime-info/-/issues/11
93 ++ QTest::newRow("x-sharedlib") << "application/x-sharedlib";
94 ++ QTest::newRow("x-executable") << "application/x-executable";
95 ++}
96 ++
97 + void OpenUrlJobTest::refuseRunningNativeExecutables()
98 + {
99 +- KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()), QStringLiteral("application/x-executable"), this);
100 ++ QFETCH(QString, mimeType);
101 ++
102 ++ KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(QCoreApplication::applicationFilePath()), mimeType, this);
103 + QVERIFY(!job->exec());
104 + QCOMPARE(job->error(), KJob::UserDefinedError);
105 + QVERIFY2(job->errorString().contains("For security reasons, launching executables is not allowed in this context."), qPrintable(job->errorString()));
106 + }
107 +
108 ++void OpenUrlJobTest::refuseRunningRemoteNativeExecutables_data()
109 ++{
110 ++ QTest::addColumn<QString>("mimeType");
111 ++ QTest::newRow("x-sharedlib") << "application/x-sharedlib";
112 ++ QTest::newRow("x-executable") << "application/x-executable";
113 ++}
114 ++
115 + void OpenUrlJobTest::refuseRunningRemoteNativeExecutables()
116 + {
117 +- KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl("protocol://host/path/exe"), QStringLiteral("application/x-executable"), this);
118 ++ QFETCH(QString, mimeType);
119 ++
120 ++ KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl("protocol://host/path/exe"), mimeType, this);
121 + job->setRunExecutables(true); // even with this enabled, an error will occur
122 + QVERIFY(!job->exec());
123 + QCOMPARE(job->error(), KJob::UserDefinedError);
124 +@@ -273,8 +293,11 @@ void OpenUrlJobTest::runScript_data()
125 + {
126 + QTest::addColumn<QString>("mimeType");
127 +
128 ++ // All text-based scripts inherit text/plain and application/x-executable, no need to test
129 ++ // all flavours (python, perl, lua, awk ...etc), this sample should be enough
130 + QTest::newRow("shellscript") << "application/x-shellscript";
131 +- QTest::newRow("native") << "application/x-executable";
132 ++ QTest::newRow("pythonscript") << "text/x-python";
133 ++ QTest::newRow("javascript") << "application/javascript";
134 + }
135 +
136 + void OpenUrlJobTest::runScript()
137 +@@ -305,16 +328,23 @@ void OpenUrlJobTest::runScript()
138 +
139 + void OpenUrlJobTest::runNativeExecutable_data()
140 + {
141 ++ QTest::addColumn<QString>("mimeType");
142 + QTest::addColumn<bool>("withHandler");
143 + QTest::addColumn<bool>("handlerRetVal");
144 +
145 +- QTest::newRow("no_handler") << false << false;
146 +- QTest::newRow("handler_false") << true << false;
147 +- QTest::newRow("handler_true") << true << true;
148 ++ QTest::newRow("no_handler_x-sharedlib") << "application/x-sharedlib" << false << false;
149 ++ QTest::newRow("handler_false_x-sharedlib") << "application/x-sharedlib" << true << false;
150 ++ QTest::newRow("handler_true_x-sharedlib") << "application/x-sharedlib" << true << true;
151 ++
152 ++ QTest::newRow("no_handler_x-executable") << "application/x-executable" << false << false;
153 ++ QTest::newRow("handler_false_x-executable") << "application/x-executable" << true << false;
154 ++ QTest::newRow("handler_true_x-executable") << "application/x-executable" << true << true;
155 ++
156 + }
157 +
158 + void OpenUrlJobTest::runNativeExecutable()
159 + {
160 ++ QFETCH(QString, mimeType);
161 + QFETCH(bool, withHandler);
162 + QFETCH(bool, handlerRetVal);
163 +
164 +@@ -335,7 +365,7 @@ void OpenUrlJobTest::runNativeExecutable()
165 + KIO::setDefaultUntrustedProgramHandler(withHandler ? &s_handler : nullptr);
166 +
167 + // When using OpenUrlJob to run the executable
168 +- KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(scriptFile), QStringLiteral("application/x-executable"), this);
169 ++ KIO::OpenUrlJob *job = new KIO::OpenUrlJob(QUrl::fromLocalFile(scriptFile), mimeType, this);
170 + job->setRunExecutables(true); // startProcess tests the case where this isn't set
171 + const bool success = job->exec();
172 +
173 +diff --git a/autotests/openurljobtest.h b/autotests/openurljobtest.h
174 +index e71987d9..f5b9a5be 100644
175 +--- a/autotests/openurljobtest.h
176 ++++ b/autotests/openurljobtest.h
177 +@@ -26,7 +26,9 @@ private Q_SLOTS:
178 +
179 + void noServiceNoHandler();
180 + void invalidUrl();
181 ++ void refuseRunningNativeExecutables_data();
182 + void refuseRunningNativeExecutables();
183 ++ void refuseRunningRemoteNativeExecutables_data();
184 + void refuseRunningRemoteNativeExecutables();
185 + void notAuthorized();
186 + void runScript_data();
187 +diff --git a/src/gui/openurljob.cpp b/src/gui/openurljob.cpp
188 +index 8ac187b4..3e35c95c 100644
189 +--- a/src/gui/openurljob.cpp
190 ++++ b/src/gui/openurljob.cpp
191 +@@ -73,9 +73,9 @@ public:
192 +
193 + private:
194 + void executeCommand();
195 +- void handleExecutables(const QMimeType &mimeType);
196 ++ void handleBinaries(const QMimeType &mimeType);
197 + void handleDesktopFiles();
198 +- void handleShellscripts();
199 ++ void handleScripts();
200 + void openInPreferredApp();
201 + void runLink(const QString &filePath, const QString &urlStr, const QString &optionalServiceName);
202 +
203 +@@ -439,14 +439,29 @@ void KIO::OpenUrlJobPrivate::emitAccessDenied()
204 + q->emitResult();
205 + }
206 +
207 +-// was: KRun::isExecutable (minus application/x-desktop and application/x-shellscript mimetypes).
208 ++// was: KRun::isExecutable (minus application/x-desktop mimetype).
209 + // Feel free to make public if needed.
210 +-static bool isExecutableMime(const QMimeType &mimeType)
211 ++static bool isBinary(const QMimeType &mimeType)
212 + {
213 +- return (mimeType.inherits(QStringLiteral("application/x-executable")) ||
214 +- /* e.g. /usr/bin/ls, see https://gitlab.freedesktop.org/xdg/shared-mime-info/-/issues/11 */
215 +- mimeType.inherits(QStringLiteral("application/x-sharedlib")) ||
216 +- mimeType.inherits(QStringLiteral("application/x-ms-dos-executable")));
217 ++ // - Binaries could be e.g.:
218 ++ // - application/x-executable
219 ++ // - application/x-sharedlib e.g. /usr/bin/ls, see
220 ++ // https://gitlab.freedesktop.org/xdg/shared-mime-info/-/issues/11
221 ++ //
222 ++ // - Mimetypes that inherit application/x-executable _and_ text/plain are scripts, these are
223 ++ // handled by handleScripts()
224 ++
225 ++ return (mimeType.inherits(QStringLiteral("application/x-executable"))
226 ++ || mimeType.inherits(QStringLiteral("application/x-sharedlib"))
227 ++ || mimeType.inherits(QStringLiteral("application/x-ms-dos-executable")));
228 ++}
229 ++
230 ++// Helper function that returns whether a file is a text-based script
231 ++// e.g. ".sh", ".csh", ".py", ".js"
232 ++static bool isTextScript(const QMimeType &mimeType)
233 ++{
234 ++ return (mimeType.inherits(QStringLiteral("application/x-executable"))
235 ++ && mimeType.inherits(QStringLiteral("text/plain")));
236 + }
237 +
238 + // Helper function that returns whether a file has the execute bit set or not.
239 +@@ -456,7 +471,7 @@ static bool hasExecuteBit(const QString &fileName)
240 + }
241 +
242 + // Handle native binaries (.e.g. /usr/bin/*); and .exe files
243 +-void KIO::OpenUrlJobPrivate::handleExecutables(const QMimeType &mimeType)
244 ++void KIO::OpenUrlJobPrivate::handleBinaries(const QMimeType &mimeType)
245 + {
246 + if (!KAuthorized::authorize(QStringLiteral("shell_access"))) {
247 + emitAccessDenied();
248 +@@ -475,11 +490,9 @@ void KIO::OpenUrlJobPrivate::handleExecutables(const QMimeType &mimeType)
249 +
250 + const QString localPath = m_url.toLocalFile();
251 +
252 +- // Check whether file is an executable script
253 +-#ifdef Q_OS_WIN
254 +- const bool isNativeBinary = !mimeType.inherits(QStringLiteral("text/plain"));
255 +-#else
256 +- const bool isNativeBinary = !mimeType.inherits(QStringLiteral("text/plain")) && !mimeType.inherits(QStringLiteral("application/x-ms-dos-executable"));
257 ++ bool isNativeBinary = true;
258 ++#ifndef Q_OS_WIN
259 ++ isNativeBinary = !mimeType.inherits(QStringLiteral("application/x-ms-dos-executable"));
260 + #endif
261 +
262 + if (m_showOpenOrExecuteDialog) {
263 +@@ -497,6 +510,8 @@ void KIO::OpenUrlJobPrivate::handleExecutables(const QMimeType &mimeType)
264 + }
265 + };
266 +
267 ++ // Ask the user for confirmation before executing this binary (for binaries
268 ++ // the dialog will only show Execute/Cancel)
269 + showOpenOrExecuteFileDialog(dialogFinished);
270 + return;
271 + }
272 +@@ -601,15 +616,15 @@ void KIO::OpenUrlJobPrivate::runUrlWithMimeType()
273 + return;
274 + }
275 +
276 +- // Shell scripts
277 +- if (mimeType.inherits(QStringLiteral("application/x-shellscript"))) {
278 +- handleShellscripts();
279 ++ // Scripts (e.g. .sh, .csh, .py, .js)
280 ++ if (isTextScript(mimeType)) {
281 ++ handleScripts();
282 + return;
283 + }
284 +
285 +- // Binaries (e.g. /usr/bin/konsole) and .exe files
286 +- if (isExecutableMime(mimeType)) {
287 +- handleExecutables(mimeType);
288 ++ // Binaries (e.g. /usr/bin/{konsole,ls}) and .exe files
289 ++ if (isBinary(mimeType)) {
290 ++ handleBinaries(mimeType);
291 + return;
292 + }
293 +
294 +@@ -677,8 +692,9 @@ void KIO::OpenUrlJobPrivate::handleDesktopFiles()
295 + openInPreferredApp();
296 + }
297 +
298 +-void KIO::OpenUrlJobPrivate::handleShellscripts()
299 ++void KIO::OpenUrlJobPrivate::handleScripts()
300 + {
301 ++ // Executable scripts of any type can run arbitrary shell commands
302 + if (!KAuthorized::authorize(QStringLiteral("shell_access"))) {
303 + emitAccessDenied();
304 + return;
305 +@@ -687,8 +703,7 @@ void KIO::OpenUrlJobPrivate::handleShellscripts()
306 + const bool isLocal = m_url.isLocalFile();
307 + const QString localPath = m_url.toLocalFile();
308 + if (!isLocal || !hasExecuteBit(localPath)) {
309 +- // Open remote shell scripts or ones without the execute bit, with the
310 +- // default application
311 ++ // Open remote scripts or ones without the execute bit, with the default application
312 + openInPreferredApp();
313 + return;
314 + }
315 +@@ -706,7 +721,7 @@ void KIO::OpenUrlJobPrivate::handleShellscripts()
316 + return;
317 + }
318 +
319 +- if (m_runExecutables) { // Local executable shell script, proceed
320 ++ if (m_runExecutables) { // Local executable script, proceed
321 + executeCommand();
322 + } else { // Open in the default (text editor) app
323 + openInPreferredApp();
324 +@@ -767,7 +782,7 @@ void KIO::OpenUrlJobPrivate::showOpenOrExecuteFileDialog(std::function<void(bool
325 +
326 + if (!s_openOrExecuteFileHandler) {
327 + // No way to ask the user whether to execute or open
328 +- if (mimeType.inherits(QStringLiteral("application/x-shellscript"))
329 ++ if (isTextScript(mimeType)
330 + || mimeType.inherits(QStringLiteral("application/x-desktop"))) { // Open text-based ones in the default app
331 + openInPreferredApp();
332 + } else {
333 +--
334 +GitLab
335 +
336
337 diff --git a/kde-frameworks/kio/kio-5.74.1-r1.ebuild b/kde-frameworks/kio/kio-5.74.1-r1.ebuild
338 index 8ba617db566..b77cae090c8 100644
339 --- a/kde-frameworks/kio/kio-5.74.1-r1.ebuild
340 +++ b/kde-frameworks/kio/kio-5.74.1-r1.ebuild
341 @@ -71,7 +71,10 @@ PDEPEND="
342 # tests hang
343 RESTRICT+=" test"
344
345 -PATCHES=( "${FILESDIR}"/${P}-kio_trash-too-strict-perms-check.patch )
346 +PATCHES=(
347 + "${FILESDIR}"/${P}-kio_trash-too-strict-perms-check.patch
348 + "${FILESDIR}"/${P}-handle-shell-scripts-consistenty.patch
349 +)
350
351 src_configure() {
352 local mycmakeargs=(