Run argv click actions through a login shell as positional params

Quickshell.execDetached(argv) ran the click target with only the shell
process's stripped environment, so GUI actions like the screenshot editor
(tensaku-edit) — resolved on the login-shell PATH the old `bash -lc` string
exec provided — stopped launching on click.

Run the argv through `bash -lc 'exec "$@"'` instead: the script text is a
constant and the arguments are passed as positional parameters, which bash
expands without re-tokenizing or re-evaluating, so injection safety is intact
while PATH and session env match the old behavior exactly.
This commit is contained in:
Ryan Hughes
2026-08-23 12:25:48 -04:00
parent 07443f3970
commit d2fd2e11c6
4 changed files with 27 additions and 16 deletions
+10 -6
View File
@@ -94,12 +94,16 @@ an action and just expect click-to-jump.
### Click commands must be argv, not shell strings
Prefer `--exec-arg` for every click command. Each `--exec-arg` contributes one
literal argument; the shell runs the resulting vector with
`Quickshell.execDetached(argv)` and **no shell**, so a value carrying data an
attacker controls — a downloaded video's title, a received filename, a crashed
process's name — is only ever a single argument and can never be reparsed as a
command. This is the parameterized form: pass untrusted data as its own
`--exec-arg` rather than quoting it into a string.
literal argument; the shell runs the resulting vector through
`Util.execArgv`, which invokes `bash -lc 'exec "$@"'` with the arguments as
**positional parameters** — never interpolated into the script text. bash
expands `"$@"` without re-tokenizing or re-evaluating it, so a value carrying
data an attacker controls — a downloaded video's title, a received filename, a
crashed process's name — is only ever a single argument and can never be
reparsed as a command. The login shell keeps the PATH and session environment
that GUI click targets (the screenshot editor, mpv, xdg-open) expect. This is
the parameterized form: pass untrusted data as its own `--exec-arg` rather than
quoting it into a string.
`--exec` is the legacy free-form variant, run through `bash -lc`. It is safe
only when the caller shell-quoted every interpolated value perfectly — the same