xdg-autostart-service: expand tilde in Exec lines

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.
This commit is contained in:
David Edmundson
2022-09-14 19:21:00 +01:00
committed by Yu Watanabe
parent f562abe296
commit 8c0a6a96fe
2 changed files with 31 additions and 2 deletions

View 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[] = {

View 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]);