ash: use pgetc_eatbnl() in more places

Part of upstream commit:

    Date:   Thu Mar 8 08:37:11 2018 +0100
    Author: Harald van Dijk <harald@gigawatt.nl>
    parser: use pgetc_eatbnl() in more places

    dash has a pgetc_eatbnl function in parser.c which skips any
    backslash-newline combinations. It's not used everywhere it could be.
    There is also some duplicated backslash-newline handling elsewhere in
    parser.c. Replace most of the calls to pgetc() with calls to
    pgetc_eatbnl() and remove the duplicated backslash-newline handling.

    Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>

Not adding "readtoken1(pgetc_eatbnl(), DQSYNTAX..." changes, since
readtoken1() handles the "starts with backslash + newline" case itself.

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
This commit is contained in:
Denys Vlasenko 2018-03-31 19:21:31 +02:00
parent ad4e961352
commit 220be537a0
7 changed files with 191 additions and 35 deletions

View File

@ -12225,7 +12225,7 @@ parseredir: {
np = stzalloc(sizeof(struct nfile));
if (c == '>') {
np->nfile.fd = 1;
c = pgetc();
c = pgetc_eatbnl();
if (c == '>')
np->type = NAPPEND;
else if (c == '|')
@ -12247,7 +12247,7 @@ parseredir: {
#endif
else { /* c == '<' */
/*np->nfile.fd = 0; - stzalloc did it */
c = pgetc();
c = pgetc_eatbnl();
switch (c) {
case '<':
if (sizeof(struct nfile) != sizeof(struct nhere)) {
@ -12257,7 +12257,7 @@ parseredir: {
np->type = NHERE;
heredoc = stzalloc(sizeof(struct heredoc));
heredoc->here = np;
c = pgetc();
c = pgetc_eatbnl();
if (c == '-') {
heredoc->striptabs = 1;
} else {
@ -12487,23 +12487,13 @@ parsebackq: {
int pc;
setprompt_if(needprompt, 2);
pc = pgetc();
pc = pgetc_eatbnl();
switch (pc) {
case '`':
goto done;
case '\\':
pc = pgetc();
if (pc == '\n') {
nlprompt();
/*
* If eating a newline, avoid putting
* the newline into the new character
* stream (via the STPUTC after the
* switch).
*/
continue;
}
pc = pgetc(); /* or pgetc_eatbnl()? why (example)? */
if (pc != '\\' && pc != '`' && pc != '$'
&& (!dblquote || pc != '"')
) {
@ -12635,7 +12625,7 @@ xxreadtoken(void)
}
setprompt_if(needprompt, 2);
for (;;) { /* until token or start of word found */
c = pgetc();
c = pgetc_eatbnl();
if (c == ' ' || c == '\t' IF_ASH_ALIAS( || c == PEOA))
continue;
@ -12644,11 +12634,7 @@ xxreadtoken(void)
continue;
pungetc();
} else if (c == '\\') {
if (pgetc() != '\n') {
pungetc();
break; /* return readtoken1(...) */
}
nlprompt();
break; /* return readtoken1(...) */
} else {
const char *p;
@ -12695,7 +12681,7 @@ xxreadtoken(void)
}
setprompt_if(needprompt, 2);
for (;;) { /* until token or start of word found */
c = pgetc();
c = pgetc_eatbnl();
switch (c) {
case ' ': case '\t':
IF_ASH_ALIAS(case PEOA:)
@ -12705,30 +12691,23 @@ xxreadtoken(void)
continue;
pungetc();
continue;
case '\\':
if (pgetc() == '\n') {
nlprompt();
continue;
}
pungetc();
goto breakloop;
case '\n':
nlnoprompt();
RETURN(TNL);
case PEOF:
RETURN(TEOF);
case '&':
if (pgetc() == '&')
if (pgetc_eatbnl() == '&')
RETURN(TAND);
pungetc();
RETURN(TBACKGND);
case '|':
if (pgetc() == '|')
if (pgetc_eatbnl() == '|')
RETURN(TOR);
pungetc();
RETURN(TPIPE);
case ';':
if (pgetc() == ';')
if (pgetc_eatbnl() == ';')
RETURN(TENDCASE);
pungetc();
RETURN(TSEMI);
@ -12736,11 +12715,9 @@ xxreadtoken(void)
RETURN(TLP);
case ')':
RETURN(TRP);
default:
goto breakloop;
}
break;
}
breakloop:
return readtoken1(c, BASESYNTAX, (char *)NULL, 0);
#undef RETURN
}

View File

@ -0,0 +1,43 @@
Quoted heredoc:
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\
Unquoted heredoc:
a b
a\
b
123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
-qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
cEOF2
Quoted -heredoc:
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\
Unquoted -heredoc:
a b
a\
b
123456 -qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
-qwerty-\t-\-\"-\'-`-\--\z-\*-\?-
123456 v-$a-\t-\-\"-\x-`-\--\z-\*-\?-
123456 v-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-
cEOF4
Done: 0

View File

@ -0,0 +1,70 @@
# Test for correct handling of backslashes.
# Note that some lines in each heredoc start with a tab.
a=qwerty
echo Quoted heredoc:
cat <<"EOF1"
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\
EOF1
echo
echo Unquoted heredoc:
cat <<EOF2
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
c\
EOF2
EOF2
echo
echo Quoted -heredoc:
cat <<-"EOF3"
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-')
c\
EOF3
# In -heredoc case the marker is detected even if it is indented.
echo
echo Unquoted -heredoc:
cat <<-EOF4
a\
b
a\\
b
123456 -$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
-$a-\t-\\-\"-\'-\`-\--\z-\*-\?-
123456 `echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-'`
123456 $(echo v'-$a-\t-\\-\"-\x-\`-\--\z-\*-\?-')
c\
EOF4
EOF4
# The marker is not detected if preceding line ends in backslash.
# TODO: marker should be detected even if it is split by line continuation:
# EOF\
# 4
# but currently hush doesn't do it. (Tab before "4" is not allowed, though.)
echo
echo "Done: $?"

View File

@ -0,0 +1,8 @@
heredoc0
Ok0:0
heredoc1
Ok1:0
heredoc2
Ok2:0
heredoc3
Ok4:0

View File

@ -0,0 +1,25 @@
cat <\
<\
EOF
heredoc0
EOF
echo Ok0:$?
cat <<\
EOF
heredoc1
EOF
echo Ok1:$?
cat <<\
- EOF
heredoc2
EOF
echo Ok2:$?
cat <\
<\
- EOF
heredoc3
EOF
echo Ok4:$?

View File

@ -0,0 +1,8 @@
heredoc0
Ok0:0
heredoc1
Ok1:0
heredoc2
Ok2:0
heredoc3
Ok4:0

View File

@ -0,0 +1,25 @@
cat <\
<\
EOF
heredoc0
EOF
echo Ok0:$?
cat <<\
EOF
heredoc1
EOF
echo Ok1:$?
cat <<\
- EOF
heredoc2
EOF
echo Ok2:$?
cat <\
<\
- EOF
heredoc3
EOF
echo Ok4:$?