`git commit -m "${{ github.event.head_commit.message }}"` splices arbitrary text
straight into a double-quoted bash string. A message containing a double quote
closes the string early and the remainder is re-parsed as shell words.
This is what broke main after #248 merged. That PR's title contained
"Unclear at this time." (with quotes), so the merge commit message did too, and
the line bash actually ran was:
git commit -m "Fill "Unclear at this time." from primary operator docs ..."
which git received as:
-m "Fill Unclear" at this "time. from primary operator docs ..."
Hence `error: pathspec 'at' did not match any file(s) known to git`, a failed
run, and the revert in 80c19fc. The data in that PR was fine — robots.py
--convert exits 0 against it and code/tests.py passes 13/13.
The same interpolation is also a script-injection vector, which is the more
important reason to change it: a PR title is attacker-controlled, and
chore: tidy"; <any command>; echo "
executes that command on the runner with the workflow's token. `inputs.message`
has the same shape in the `if [ -n ... ]` test and its own `git commit -m`, so
all three are moved.
Passing through `env:` and quoting the shell variable is GitHub's documented
recommendation for untrusted values. The variable is expanded by bash after
parsing, so quotes, newlines and `$(...)` stay literal text.
Verified: code/tests.py 13/13 · python code/robots.py --convert exits 0 and
leaves robots.txt, table-of-bot-metrics.md and every server-config output
byte-identical · reproduced both the parse failure and the injection locally
against the old form, and confirmed the env form commits the same message
verbatim, quotes included.
The name dark_visitors.py gives the impression that the code is entirely
related to the dark visitors website, whereas the update command relates
to dark visitors and the convert command is unrelated to dark visitors.