Recognize --exec only after the positionals
A greedy pre-scan matched the first --exec token anywhere on the line, so an untrusted headline or description literally equal to "--exec" could be mistaken for the delimiter. It always failed closed (the following token became a dash-option argv[0] that parseExecArgv rejects), but it was a latent footgun surfaced by an adversarial review. Detect --exec only in the trailing-option loop, after the headline/description positionals are captured. A headline that is the string "--exec" is now kept as text and the real trailing --exec still wins. The residual — a description exactly equal to "--exec" losing its click action — is an inherent, harmless CLI ambiguity for a value identical to the delimiter.
This commit is contained in:
@@ -17,25 +17,6 @@ exec_present=0
|
|||||||
args=()
|
args=()
|
||||||
parsed_option_args=0
|
parsed_option_args=0
|
||||||
|
|
||||||
# Split off the click command first: everything after --exec is its argv. The
|
|
||||||
# caller's shell has already tokenized those words into discrete arguments, and
|
|
||||||
# the shell runs them as-is (never re-parsed by a shell), so a value carrying
|
|
||||||
# untrusted data — a title, a filename — is only ever one argument and can never
|
|
||||||
# become a command. --exec therefore consumes the rest of the line and must
|
|
||||||
# come last.
|
|
||||||
pre_args=()
|
|
||||||
while (($# > 0)); do
|
|
||||||
if [[ $1 == "--exec" ]]; then
|
|
||||||
shift
|
|
||||||
exec_args=("$@")
|
|
||||||
exec_present=1
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
pre_args+=("$1")
|
|
||||||
shift
|
|
||||||
done
|
|
||||||
set -- "${pre_args[@]}"
|
|
||||||
|
|
||||||
parse_omarchy_option() {
|
parse_omarchy_option() {
|
||||||
case $1 in
|
case $1 in
|
||||||
-g | --glyph)
|
-g | --glyph)
|
||||||
@@ -101,7 +82,19 @@ if (($# > 0)) && [[ $1 != -* ]]; then
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
while (($# > 0)); do
|
while (($# > 0)); do
|
||||||
if parse_omarchy_option "$@"; then
|
if [[ $1 == "--exec" ]]; then
|
||||||
|
# --exec consumes the rest of the line as the click command's argv. The
|
||||||
|
# caller's shell already tokenized those words into discrete arguments, and
|
||||||
|
# the shell runs them as-is (never re-parsed), so untrusted data in an
|
||||||
|
# argument is only ever one argument and can never become a command.
|
||||||
|
# Detected only here, after the headline/description positionals are
|
||||||
|
# captured, so an untrusted headline that is literally "--exec" is taken as
|
||||||
|
# text and can't be mistaken for the delimiter. --exec therefore comes last.
|
||||||
|
shift
|
||||||
|
exec_args=("$@")
|
||||||
|
exec_present=1
|
||||||
|
break
|
||||||
|
elif parse_omarchy_option "$@"; then
|
||||||
shift "$parsed_option_args"
|
shift "$parsed_option_args"
|
||||||
else
|
else
|
||||||
args+=("$1")
|
args+=("$1")
|
||||||
|
|||||||
@@ -85,3 +85,15 @@ if send "Head" --exec 2>/dev/null; then
|
|||||||
fail "notification wrapper rejects --exec with no command"
|
fail "notification wrapper rejects --exec with no command"
|
||||||
fi
|
fi
|
||||||
pass "notification wrapper rejects --exec with no command"
|
pass "notification wrapper rejects --exec with no command"
|
||||||
|
|
||||||
|
# --exec is recognized only after the positionals, so an untrusted headline or
|
||||||
|
# description that is literally "--exec" is taken as text and cannot be mistaken
|
||||||
|
# for the delimiter (the real --exec later still wins).
|
||||||
|
: >"$args_file"
|
||||||
|
send "--exec" "a body" --image /tmp/i.png --exec mpv -- /tmp/v.mp4 >/dev/null
|
||||||
|
argv_hint=$(grep -- "--hint=string:omarchy-exec-argv:" "$args_file")
|
||||||
|
argv_json=${argv_hint#--hint=string:omarchy-exec-argv:}
|
||||||
|
[[ $(jq -c '.' <<<"$argv_json") == '["mpv","--","/tmp/v.mp4"]' ]] || fail "notification wrapper ignores a --exec-looking headline as the delimiter" "$argv_json"
|
||||||
|
grep -qx -- "--exec" "$args_file" || fail "notification wrapper keeps a --exec-looking headline as text"
|
||||||
|
grep -q 'image-path:/tmp/i.png' "$args_file" || fail "notification wrapper still parses options after a --exec-looking headline"
|
||||||
|
pass "notification wrapper does not treat a --exec-looking positional as the delimiter"
|
||||||
|
|||||||
Reference in New Issue
Block a user