fix(hooks): the args-heredoc guard checks every opener with a line after it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-10-28 15:36:21 +01:00
commit eca974aaa6
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
2 changed files with 37 additions and 11 deletions

View file

@ -417,3 +417,23 @@ test('[ARG] every shipped parser heredoc block passes the guard', async () => {
await expectArgsAllowed(command);
}
});
// HDG (fix round 4.5b, part 2) -- bash reads a heredoc body only from the
// lines after the opener's line. A command that only mentions the opener, with
// no non-blank line after it, has nothing that can close early and nothing to
// expand, so it passes. Every opener with a line after it is checked, so a
// quoted first mention cannot hide a later unquoted heredoc.
test('[HDG] a command that only mentions the opener on its last line passes, and every opener with a line after it is checked', async () => {
await expectArgsAllowed(`grep -n "<<'${ARGS_DELIM}'" commands/trekreview.md`);
await expectArgsAllowed(`grep -n "<<'${ARGS_DELIM}'" commands/trekreview.md\n`);
await expectArgsAllowed(`grep -n "<<${ARGS_DELIM}" commands/trekreview.md\n`);
await expectArgsAllowed(`echo hi\ngrep -n "<<'${ARGS_DELIM}'" f`);
// A quoted first mention must not hide a later unquoted heredoc.
await expectArgsBlocked(`echo "<<'${ARGS_DELIM}'"\n${PARSER_LINE} <<${ARGS_DELIM}\nbrief.md $(touch PWNED)\n${ARGS_DELIM}`);
// Control: a real heredoc of the delimiter is checked as before.
await expectArgsBlocked(`${PARSER_LINE} <<'${ARGS_DELIM}' 2>&1\nbrief.md\n${ARGS_DELIM}\ntouch PWNED`);
await expectArgsBlocked(`${PARSER_LINE} <<'${ARGS_DELIM}'\nbrief.md\n${ARGS_DELIM}\ntouch PWNED\n${ARGS_DELIM}`);
await expectArgsBlocked(`${PARSER_LINE} <<'${ARGS_DELIM}'\n\n${ARGS_DELIM}\ntouch PWNED`);
await expectArgsBlocked(`echo hi\n${PARSER_LINE} <<'${ARGS_DELIM}'\nbrief.md\n${ARGS_DELIM}\ntouch PWNED\n${ARGS_DELIM}`);
await expectArgsBlocked(`${PARSER_LINE} <<${ARGS_DELIM}\nbrief.md\n${ARGS_DELIM}`);
});