Page MenuHomeFreeBSD

sh: Fix heredoc at certain places in case and for
ClosedPublic

Authored by jilles on Oct 24 2021, 9:57 PM.

Details

Summary

After an unescaped newline, there may be a here-document. Some places in
case and for did not check for one.

Test Plan

Testsuite, including three new tests

Diff Detail

Repository
R10 FreeBSD src repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

The here-document shall be treated as a single word that begins after the next <newline>

https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_07_04

Huh interesting. I did not know this. dash (git) fails on heredoc14.0 but the rest of the shells, and other scripts, pass outside of sh.
I was surprised about this but there is a clear example at that doc showing ; is allowed.

An example of a here-document follows:

cat <<eof1; cat <<eof2
Hi,
eof1
Helene.
eof2
bin/sh/parser.c
483–485

dash also has CHKKWD | CHKALIAS here but I don't see how a keyword or alias is valid here.

531–532

And dash checks for CHKKWD here too but seems wrong.

This revision is now accepted and ready to land.Oct 26 2021, 5:06 PM
bin/sh/parser.c
483–485

Like most shells, dash recognizes in as a keyword, resulting in a syntax error if it occurs unquoted as the first word of a command. zsh and FreeBSD sh only recognize in in the appropriate location in a case or for command, allowing it unquoted as a utility or function name.

Recognizing aliases here is an extension shared by a few other shells. In older shells, this happened because keyword and alias recognition were tied together. For example,

sh -c 'alias DO=do; eval "$1"' arg0 'for i in a b c; DO echo ".$i"; done'

works with a variety of shells, and

sh -c 'alias IN=in; eval "$1"' arg0 'for i IN a b c; do echo ".$i"; done'

works a bit less commonly. Per POSIX, this is allowed because the syntax is otherwise invalid. Expanding an alias in in a for command would not be allowed, however.