diff options
author | Jilles Tjoelker <jilles@FreeBSD.org> | 2021-10-14 20:53:42 +0000 |
---|---|---|
committer | Jilles Tjoelker <jilles@FreeBSD.org> | 2021-10-27 19:05:19 +0000 |
commit | 72f750dc7c7324c3999e4d6cfbb2758694893cdd (patch) | |
tree | 76ef0d831d77f7c74e082bf950649e439428eca8 /bin | |
parent | 628c3b307fb29e9812008b8a0b3ccb73e0f0ecfa (diff) | |
download | src-72f750dc7c7324c3999e4d6cfbb2758694893cdd.tar.gz src-72f750dc7c7324c3999e4d6cfbb2758694893cdd.zip |
sh: Fix heredoc at certain places in case and for
After an unescaped newline, there may be a here-document. Some places in
case and for did not check for one.
Reviewed by: bdrewery
Differential Revision: https://reviews.freebsd.org/D32628
Diffstat (limited to 'bin')
-rw-r--r-- | bin/sh/parser.c | 16 | ||||
-rw-r--r-- | bin/sh/tests/parser/Makefile | 3 | ||||
-rw-r--r-- | bin/sh/tests/parser/heredoc14.0 | 8 | ||||
-rw-r--r-- | bin/sh/tests/parser/heredoc15.0 | 9 | ||||
-rw-r--r-- | bin/sh/tests/parser/heredoc16.0 | 8 |
5 files changed, 37 insertions, 7 deletions
diff --git a/bin/sh/parser.c b/bin/sh/parser.c index 297d19d4d9b6..e75798800edf 100644 --- a/bin/sh/parser.c +++ b/bin/sh/parser.c @@ -480,9 +480,9 @@ command(void) n1 = (union node *)stalloc(sizeof (struct nfor)); n1->type = NFOR; n1->nfor.var = wordtext; - while (readtoken() == TNL) - ; - if (lasttoken == TWORD && ! quoteflag && equal(wordtext, "in")) { + checkkwd = CHKNL; + if (readtoken() == TWORD && !quoteflag && + equal(wordtext, "in")) { app = ≈ while (readtoken() == TWORD) { n2 = makename(); @@ -491,7 +491,9 @@ command(void) } *app = NULL; n1->nfor.args = ap; - if (lasttoken != TNL && lasttoken != TSEMI) + if (lasttoken == TNL) + tokpushback++; + else if (lasttoken != TSEMI) synexpect(-1); } else { static char argvars[5] = { @@ -507,7 +509,7 @@ command(void) * Newline or semicolon here is optional (but note * that the original Bourne shell only allowed NL). */ - if (lasttoken != TNL && lasttoken != TSEMI) + if (lasttoken != TSEMI) tokpushback++; } checkkwd = CHKNL | CHKKWD | CHKALIAS; @@ -526,8 +528,8 @@ command(void) n1->type = NCASE; consumetoken(TWORD); n1->ncase.expr = makename(); - while (readtoken() == TNL); - if (lasttoken != TWORD || ! equal(wordtext, "in")) + checkkwd = CHKNL; + if (readtoken() != TWORD || ! equal(wordtext, "in")) synerror("expecting \"in\""); cpp = &n1->ncase.cases; checkkwd = CHKNL | CHKKWD, readtoken(); diff --git a/bin/sh/tests/parser/Makefile b/bin/sh/tests/parser/Makefile index f3a15badeb52..3239f5bccd84 100644 --- a/bin/sh/tests/parser/Makefile +++ b/bin/sh/tests/parser/Makefile @@ -65,6 +65,9 @@ ${PACKAGE}FILES+= heredoc10.0 ${PACKAGE}FILES+= heredoc11.0 ${PACKAGE}FILES+= heredoc12.0 ${PACKAGE}FILES+= heredoc13.0 +${PACKAGE}FILES+= heredoc14.0 +${PACKAGE}FILES+= heredoc15.0 +${PACKAGE}FILES+= heredoc16.0 ${PACKAGE}FILES+= line-cont1.0 ${PACKAGE}FILES+= line-cont2.0 ${PACKAGE}FILES+= line-cont3.0 diff --git a/bin/sh/tests/parser/heredoc14.0 b/bin/sh/tests/parser/heredoc14.0 new file mode 100644 index 000000000000..036be53dc0c9 --- /dev/null +++ b/bin/sh/tests/parser/heredoc14.0 @@ -0,0 +1,8 @@ +# +read x <<EOF; for i in "$x" +value +EOF +do + x=$x.$i +done +[ "$x" = value.value ] diff --git a/bin/sh/tests/parser/heredoc15.0 b/bin/sh/tests/parser/heredoc15.0 new file mode 100644 index 000000000000..94c5c5f31b18 --- /dev/null +++ b/bin/sh/tests/parser/heredoc15.0 @@ -0,0 +1,9 @@ +# +set -- dummy +read x <<EOF; for i +value +EOF +do + x=$x.$i +done +[ "$x" = value.dummy ] diff --git a/bin/sh/tests/parser/heredoc16.0 b/bin/sh/tests/parser/heredoc16.0 new file mode 100644 index 000000000000..84e5e02ae3e1 --- /dev/null +++ b/bin/sh/tests/parser/heredoc16.0 @@ -0,0 +1,8 @@ +# +read x <<EOF; case $x +value +EOF +in + value) x=$x.extended +esac +[ "$x" = value.extended ] |