xdg-autostart-service: Fix binary escaping and simplify code a bit

Instead of escaping each component separately, we can instead use
quote_command_line. Doing so simplifies the code and fixes an issue
where spaces inside the executable name were not escaped.

Co-Authored-By: David Edmundson <kde@davidedmundson.co.uk>
This commit is contained in:
Benjamin Berg
2022-03-25 14:50:41 +09:00
committed by Yu Watanabe
co-authored by David Edmundson
parent 8603a229e9
commit c2b42ec413
2 changed files with 8 additions and 19 deletions
@@ -25,13 +25,13 @@ static void test_xdg_format_exec_start_one(const char *exec, const char *expecte
}
TEST(xdg_format_exec_start) {
test_xdg_format_exec_start_one("/bin/sleep 100", "/bin/sleep \"100\"");
test_xdg_format_exec_start_one("/bin/sleep 100", "/bin/sleep 100");
/* All standardised % identifiers are stripped. */
test_xdg_format_exec_start_one("/bin/sleep %f \"%F\" %u %U %d %D\t%n %N %i %c %k %v %m", "/bin/sleep");
/* Unknown % identifier currently remain, but are escaped. */
test_xdg_format_exec_start_one("/bin/sleep %X \"%Y\"", "/bin/sleep \"%%X\" \"%%Y\"");
test_xdg_format_exec_start_one("/bin/sleep %X \"%Y\"", "/bin/sleep %%X %%Y");
test_xdg_format_exec_start_one("/bin/sleep \";\\\"\"", "/bin/sleep \";\\\"\"");
}
@@ -396,7 +396,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, *p = NULL, *escaped = NULL, *quoted = NULL;
_cleanup_free_ char *c = NULL, *raw = NULL, *percent = NULL;
ssize_t l;
l = cunescape(exec_split[i], 0, &c);
@@ -412,11 +412,7 @@ int xdg_autostart_format_exec_start(
if (r < 0)
return log_info_errno(r, "Exec binary '%s' does not exist: %m", c);
escaped = cescape(executable);
if (!escaped)
return log_oom();
free_and_replace(exec_split[n++], escaped);
free_and_replace(exec_split[n++], executable);
continue;
}
@@ -445,23 +441,16 @@ int xdg_autostart_format_exec_start(
raw = strreplace(c, "%%", "%");
if (!raw)
return log_oom();
p = strreplace(raw, "%", "%%");
if (!p)
return log_oom();
escaped = cescape(p);
if (!escaped)
percent = strreplace(raw, "%", "%%");
if (!percent)
return log_oom();
quoted = strjoin("\"", escaped, "\"");
if (!quoted)
return log_oom();
free_and_replace(exec_split[n++], quoted);
free_and_replace(exec_split[n++], percent);
}
for (; exec_split[n]; n++)
exec_split[n] = mfree(exec_split[n]);
res = strv_join(exec_split, " ");
res = quote_command_line(exec_split, SHELL_ESCAPE_EMPTY);
if (!res)
return log_oom();