From a5e7ada2b6ea979b2fa59a7bc6803728ee40da6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Danielle=20For=C3=A9?= Date: Mon, 9 Dec 2024 14:01:51 -0800 Subject: [PATCH] Tests: add unsafe paste test --- src/Utils.vala | 15 +++++++++++++++ src/Widgets/TerminalWidget.vala | 8 ++------ src/meson.build | 2 ++ src/tests/UnsafePasteTest.vala | 34 +++++++++++++++++++++++++++++++++ src/tests/meson.build | 12 ++++++++++++ 5 files changed, 65 insertions(+), 6 deletions(-) create mode 100644 src/tests/UnsafePasteTest.vala create mode 100644 src/tests/meson.build diff --git a/src/Utils.vala b/src/Utils.vala index 93c9f7e530..219a6e73cd 100644 --- a/src/Utils.vala +++ b/src/Utils.vala @@ -120,6 +120,21 @@ namespace Terminal.Utils { return uri; } + public bool is_safe_paste (string text, out string msg) { + if ("\n" in text || "&" in text || "|" in text || ";" in text ) { + msg = _("The pasted text may contain multiple commands"); + return false; + } + + if ("sudo " in text || "doas " in text || "run0 " in text || "pkexec " in text || "su " in text) { + msg = _("The pasted text may be trying to gain administrative access"); + return false; + } + + msg = null; + return true; + } + public string? escape_uri (string uri, bool allow_utf8 = true, bool allow_single_quote = true) { // We only want to allow '#' in appropriate position for fragment identifier, i.e. after the last directory separator. var placeholder = "::::::"; diff --git a/src/Widgets/TerminalWidget.vala b/src/Widgets/TerminalWidget.vala index dee5445593..3bbc51a86b 100644 --- a/src/Widgets/TerminalWidget.vala +++ b/src/Widgets/TerminalWidget.vala @@ -537,12 +537,8 @@ namespace Terminal { } - string? warn_text = null; - if ("\n" in text || "&" in text || "|" in text || ";" in text ) { - warn_text = _("The pasted text may contain multiple commands"); - } else if ("sudo " in text || "doas " in text || "run0 " in text || "pkexec " in text || "su " in text) { - warn_text = _("The pasted text may be trying to gain administrative access"); - } + string? warn_text; + Utils.is_safe_paste (text, out warn_text); // No user interaction for safe commands if (warn_text == null) { diff --git a/src/meson.build b/src/meson.build index ca3f4f75ff..a7a5f86e58 100644 --- a/src/meson.build +++ b/src/meson.build @@ -71,3 +71,5 @@ test( protocol: 'tap', depends: test_schemas ) + +subdir('tests') diff --git a/src/tests/UnsafePasteTest.vala b/src/tests/UnsafePasteTest.vala new file mode 100644 index 0000000000..259bdbef67 --- /dev/null +++ b/src/tests/UnsafePasteTest.vala @@ -0,0 +1,34 @@ +/* + * SPDX-License-Identifier: GPL-3.0-or-later + * SPDX-FileCopyrightText: 2024 elementary, Inc. (https://elementary.io) + */ + +private void main (string[] args) { + Test.init (ref args); + + Test.add_func ("/valid", () => { + string msg; + + // false positive for su + assert (Terminal.Utils.is_safe_paste ("suspend", out msg)); + }); + + Test.add_func ("/invalid", () => { + string msg; + + // Elevated permissions + assert (!Terminal.Utils.is_safe_paste ("doas pacman -Syu", out msg)); + assert (!Terminal.Utils.is_safe_paste ("pkexec visudo", out msg)); + assert (!Terminal.Utils.is_safe_paste ("run0 --nice=19 my-task-with-low-priority", out msg)); + assert (!Terminal.Utils.is_safe_paste ("su username", out msg)); + assert (!Terminal.Utils.is_safe_paste ("sudo apt autoremove", out msg)); + + // Multi-line commands + assert (!Terminal.Utils.is_safe_paste ("\n", out msg)); + assert (!Terminal.Utils.is_safe_paste ("&", out msg)); + assert (!Terminal.Utils.is_safe_paste ("|", out msg)); + assert (!Terminal.Utils.is_safe_paste (";", out msg)); + }); + + Test.run (); +} diff --git a/src/tests/meson.build b/src/tests/meson.build new file mode 100644 index 0000000000..f963f4d93b --- /dev/null +++ b/src/tests/meson.build @@ -0,0 +1,12 @@ +unsafe_paste_test = executable( + 'UnsafePasteTest', + 'UnsafePasteTest.vala', + meson.project_source_root() / 'src' / 'Utils.vala', + dependencies: [ + glib_dep, + gtk_dep + ], + install: false +) + +test('UnsafePaste Test', unsafe_paste_test)