From 220be537a03f029e1e619003d6f7def10103a156 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sat, 31 Mar 2018 19:21:31 +0200 Subject: [PATCH] ash: use pgetc_eatbnl() in more places Part of upstream commit: Date: Thu Mar 8 08:37:11 2018 +0100 Author: Harald van Dijk 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 Not adding "readtoken1(pgetc_eatbnl(), DQSYNTAX..." changes, since readtoken1() handles the "starts with backslash + newline" case itself. Signed-off-by: Denys Vlasenko --- shell/ash.c | 47 ++++--------- .../ash-heredoc/heredoc_backslash1.right | 43 ++++++++++++ .../ash-heredoc/heredoc_backslash1.tests | 70 +++++++++++++++++++ .../heredoc_bkslash_newline1.right | 8 +++ .../heredoc_bkslash_newline1.tests | 25 +++++++ .../heredoc_bkslash_newline1.right | 8 +++ .../heredoc_bkslash_newline1.tests | 25 +++++++ 7 files changed, 191 insertions(+), 35 deletions(-) create mode 100644 shell/ash_test/ash-heredoc/heredoc_backslash1.right create mode 100755 shell/ash_test/ash-heredoc/heredoc_backslash1.tests create mode 100644 shell/ash_test/ash-heredoc/heredoc_bkslash_newline1.right create mode 100755 shell/ash_test/ash-heredoc/heredoc_bkslash_newline1.tests create mode 100644 shell/hush_test/hush-heredoc/heredoc_bkslash_newline1.right create mode 100755 shell/hush_test/hush-heredoc/heredoc_bkslash_newline1.tests diff --git a/shell/ash.c b/shell/ash.c index 2ed802d2e..a7767b4f8 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -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 } diff --git a/shell/ash_test/ash-heredoc/heredoc_backslash1.right b/shell/ash_test/ash-heredoc/heredoc_backslash1.right new file mode 100644 index 000000000..6a6114821 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_backslash1.right @@ -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 diff --git a/shell/ash_test/ash-heredoc/heredoc_backslash1.tests b/shell/ash_test/ash-heredoc/heredoc_backslash1.tests new file mode 100755 index 000000000..501af5490 --- /dev/null +++ b/shell/ash_test/ash-heredoc/heredoc_backslash1.tests @@ -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 <