From 1e5111b0f80b1f3d7f2fc8254cb70de067317403 Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Sun, 1 Apr 2018 03:04:55 +0200 Subject: [PATCH] ash,hush: handle a few more bkslash-newline cases Signed-off-by: Denys Vlasenko --- shell/ash.c | 2 +- shell/ash_test/ash-parsing/bkslash_newline1.right | 4 ++++ shell/ash_test/ash-parsing/bkslash_newline1.tests | 8 ++++++++ shell/ash_test/ash-parsing/bkslash_newline2.right | 4 ++++ shell/ash_test/ash-parsing/bkslash_newline2.tests | 4 ++++ shell/hush.c | 14 ++++++++++++-- .../hush_test/hush-parsing/bkslash_newline1.right | 4 ++++ .../hush_test/hush-parsing/bkslash_newline1.tests | 8 ++++++++ .../hush_test/hush-parsing/bkslash_newline2.right | 4 ++++ .../hush_test/hush-parsing/bkslash_newline2.tests | 4 ++++ 10 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 shell/ash_test/ash-parsing/bkslash_newline1.right create mode 100755 shell/ash_test/ash-parsing/bkslash_newline1.tests create mode 100644 shell/ash_test/ash-parsing/bkslash_newline2.right create mode 100755 shell/ash_test/ash-parsing/bkslash_newline2.tests create mode 100644 shell/hush_test/hush-parsing/bkslash_newline1.right create mode 100755 shell/hush_test/hush-parsing/bkslash_newline1.tests create mode 100644 shell/hush_test/hush-parsing/bkslash_newline2.right create mode 100755 shell/hush_test/hush-parsing/bkslash_newline2.tests diff --git a/shell/ash.c b/shell/ash.c index a7767b4f8..454bc3317 100644 --- a/shell/ash.c +++ b/shell/ash.c @@ -12649,7 +12649,7 @@ xxreadtoken(void) break; /* return readtoken1(...) */ if ((int)(p - xxreadtoken_chars) >= xxreadtoken_singles) { - int cc = pgetc(); + int cc = pgetc_eatbnl(); if (cc == c) { /* double occurrence? */ p += xxreadtoken_doubles + 1; } else { diff --git a/shell/ash_test/ash-parsing/bkslash_newline1.right b/shell/ash_test/ash-parsing/bkslash_newline1.right new file mode 100644 index 000000000..97ea0c197 --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline1.right @@ -0,0 +1,4 @@ +and1 +and2 +or1 +ok diff --git a/shell/ash_test/ash-parsing/bkslash_newline1.tests b/shell/ash_test/ash-parsing/bkslash_newline1.tests new file mode 100755 index 000000000..6e374c4fb --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline1.tests @@ -0,0 +1,8 @@ +echo and1 &\ +& echo and2 + +echo or1 |\ +| echo NOT SHOWN + +case w in a) echo SKIP;\ +; w) echo ok;; esac; diff --git a/shell/ash_test/ash-parsing/bkslash_newline2.right b/shell/ash_test/ash-parsing/bkslash_newline2.right new file mode 100644 index 000000000..c863c5453 --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline2.right @@ -0,0 +1,4 @@ +Line with one backslash: +\ + +Ok:0 diff --git a/shell/ash_test/ash-parsing/bkslash_newline2.tests b/shell/ash_test/ash-parsing/bkslash_newline2.tests new file mode 100755 index 000000000..47d63042d --- /dev/null +++ b/shell/ash_test/ash-parsing/bkslash_newline2.tests @@ -0,0 +1,4 @@ +echo Line with one backslash: +echo '\ +' +echo Ok:$? diff --git a/shell/hush.c b/shell/hush.c index 533d45ac3..4b8641d19 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -4980,8 +4980,14 @@ static struct pipe *parse_stream(char **pstring, nommu_addchr(&ctx.as_string, ch); next = '\0'; - if (ch != '\n') + if (ch != '\n') { next = i_peek(input); + /* Can't use i_peek_and_eat_bkslash_nl(input) here: + * echo '\ + * ' + * will break. + */ + } is_special = "{}<>;&|()#'" /* special outside of "str" */ "\\$\"" IF_HUSH_TICK("`") /* always special */ @@ -5375,7 +5381,7 @@ static struct pipe *parse_stream(char **pstring, /* Eat multiple semicolons, detect * whether it means something special */ while (1) { - ch = i_peek(input); + ch = i_peek_and_eat_bkslash_nl(input); if (ch != ';') break; ch = i_getch(input); @@ -5397,6 +5403,8 @@ static struct pipe *parse_stream(char **pstring, if (done_word(&dest, &ctx)) { goto parse_error; } + if (next == '\\') + next = i_peek_and_eat_bkslash_nl(input); if (next == '&') { ch = i_getch(input); nommu_addchr(&ctx.as_string, ch); @@ -5413,6 +5421,8 @@ static struct pipe *parse_stream(char **pstring, if (ctx.ctx_res_w == RES_MATCH) break; /* we are in case's "word | word)" */ #endif + if (next == '\\') + next = i_peek_and_eat_bkslash_nl(input); if (next == '|') { /* || */ ch = i_getch(input); nommu_addchr(&ctx.as_string, ch); diff --git a/shell/hush_test/hush-parsing/bkslash_newline1.right b/shell/hush_test/hush-parsing/bkslash_newline1.right new file mode 100644 index 000000000..97ea0c197 --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline1.right @@ -0,0 +1,4 @@ +and1 +and2 +or1 +ok diff --git a/shell/hush_test/hush-parsing/bkslash_newline1.tests b/shell/hush_test/hush-parsing/bkslash_newline1.tests new file mode 100755 index 000000000..6e374c4fb --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline1.tests @@ -0,0 +1,8 @@ +echo and1 &\ +& echo and2 + +echo or1 |\ +| echo NOT SHOWN + +case w in a) echo SKIP;\ +; w) echo ok;; esac; diff --git a/shell/hush_test/hush-parsing/bkslash_newline2.right b/shell/hush_test/hush-parsing/bkslash_newline2.right new file mode 100644 index 000000000..c863c5453 --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline2.right @@ -0,0 +1,4 @@ +Line with one backslash: +\ + +Ok:0 diff --git a/shell/hush_test/hush-parsing/bkslash_newline2.tests b/shell/hush_test/hush-parsing/bkslash_newline2.tests new file mode 100755 index 000000000..47d63042d --- /dev/null +++ b/shell/hush_test/hush-parsing/bkslash_newline2.tests @@ -0,0 +1,4 @@ +echo Line with one backslash: +echo '\ +' +echo Ok:$?