]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
xdg-autostart-service: expand tilde in Exec lines
authorDavid Edmundson <kde@davidedmundson.co.uk>
Wed, 14 Sep 2022 18:21:00 +0000 (19:21 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 15 Sep 2022 18:43:17 +0000 (03:43 +0900)
In typical desktop file parsing it is expected that "~" expands to a
home directory.

Users may write an autostart file with "Exec=myCoolService
~/.someSpecialConfig" which worked before the systemd migration.

src/xdg-autostart-generator/test-xdg-autostart.c
src/xdg-autostart-generator/xdg-autostart-service.c

index 7866d3a7b4a148d779c5473eefbe333454feb07d..e11f3d9385d1c4f08c715a9827f0691b9b40cd09 100644 (file)
@@ -25,6 +25,11 @@ static void test_xdg_format_exec_start_one(const char *exec, const char *expecte
 }
 
 TEST(xdg_format_exec_start) {
+        _cleanup_free_ char *home = NULL;
+        _cleanup_free_ char *expected1, *expected2 = NULL;
+
+        assert_se(get_home_dir(&home) >= 0);
+
         test_xdg_format_exec_start_one("/bin/sleep 100", "/bin/sleep 100");
 
         /* All standardised % identifiers are stripped. */
@@ -34,6 +39,14 @@ TEST(xdg_format_exec_start) {
         test_xdg_format_exec_start_one("/bin/sleep %X \"%Y\"", "/bin/sleep %%X %%Y");
 
         test_xdg_format_exec_start_one("/bin/sleep \";\\\"\"", "/bin/sleep \";\\\"\"");
+
+        /* tilde is expanded only if standalone or at the start of a path */
+        expected1 = strjoin("/bin/ls ", home);
+        test_xdg_format_exec_start_one("/bin/ls ~", expected1);
+        expected2 = strjoin("/bin/ls ", home, "/foo");
+        test_xdg_format_exec_start_one("/bin/ls \"~/foo\"", expected2);
+        test_xdg_format_exec_start_one("/bin/ls ~foo", "/bin/ls ~foo");
+        test_xdg_format_exec_start_one("/bin/ls foo~", "/bin/ls foo~");
 }
 
 static const char* const xdg_desktop_file[] = {
index 56cc4ceeb9abebe9bacc34826864ed9527bec94a..5aa74fe37a4cc51f3733f357adf3b9b4e3d6dbf1 100644 (file)
@@ -18,6 +18,7 @@
 #include "string-util.h"
 #include "strv.h"
 #include "unit-name.h"
+#include "user-util.h"
 
 XdgAutostartService* xdg_autostart_service_free(XdgAutostartService *s) {
         if (!s)
@@ -392,7 +393,7 @@ int xdg_autostart_format_exec_start(
 
         first_arg = true;
         for (i = n = 0; exec_split[i]; i++) {
-                _cleanup_free_ char *c = NULL, *raw = NULL, *percent = NULL;
+                _cleanup_free_ char *c = NULL, *raw = NULL, *percent = NULL, *tilde_expanded = NULL;
                 ssize_t l;
 
                 l = cunescape(exec_split[i], 0, &c);
@@ -441,7 +442,22 @@ int xdg_autostart_format_exec_start(
                 if (!percent)
                         return log_oom();
 
-                free_and_replace(exec_split[n++], percent);
+                /*
+                 * Expand ~ if it comes at the beginning of an argument to form a path
+                 */
+                if (percent[0] == '~' && (isempty(percent + 1) || path_is_absolute(percent + 1))) {
+                        _cleanup_free_ char *home = NULL;
+
+                        r = get_home_dir(&home);
+                        if (r < 0)
+                                return r;
+
+                        tilde_expanded = strjoin(home, &percent[1]);
+                        if (!tilde_expanded)
+                                return log_oom();
+                        free_and_replace(exec_split[n++], tilde_expanded);
+                } else
+                        free_and_replace(exec_split[n++], percent);
         }
         for (; exec_split[n]; n++)
                 exec_split[n] = mfree(exec_split[n]);