aboutsummaryrefslogtreecommitdiff
path: root/shell
diff options
context:
space:
mode:
Diffstat (limited to 'shell')
-rw-r--r--shell/ash.c11
-rw-r--r--shell/ash_test/ash-misc/control_char3.right1
-rwxr-xr-xshell/ash_test/ash-misc/control_char3.tests2
-rw-r--r--shell/ash_test/ash-misc/control_char4.right1
-rwxr-xr-xshell/ash_test/ash-misc/control_char4.tests2
-rw-r--r--shell/ash_test/ash-parsing/bkslash_newline4.right4
-rwxr-xr-xshell/ash_test/ash-parsing/bkslash_newline4.tests14
-rw-r--r--shell/hush.c47
-rw-r--r--shell/hush_test/hush-misc/control_char3.right1
-rwxr-xr-xshell/hush_test/hush-misc/control_char3.tests2
-rw-r--r--shell/hush_test/hush-misc/control_char4.right1
-rwxr-xr-xshell/hush_test/hush-misc/control_char4.tests2
-rw-r--r--shell/hush_test/hush-parsing/bkslash_newline4.right4
-rwxr-xr-xshell/hush_test/hush-parsing/bkslash_newline4.tests14
-rw-r--r--shell/hush_test/hush-vars/var6.right2
15 files changed, 97 insertions, 11 deletions
diff --git a/shell/ash.c b/shell/ash.c
index bab6138da..4ae42595d 100644
--- a/shell/ash.c
+++ b/shell/ash.c
@@ -13572,7 +13572,7 @@ parsesub: {
13572 do { 13572 do {
13573 STPUTC(c, out); 13573 STPUTC(c, out);
13574 c = pgetc_eatbnl(); 13574 c = pgetc_eatbnl();
13575 } while (!subtype && isdigit(c)); 13575 } while ((subtype == 0 || subtype == VSLENGTH) && isdigit(c));
13576 } else if (c != '}') { 13576 } else if (c != '}') {
13577 /* $[{[#]]<specialchar>[}] */ 13577 /* $[{[#]]<specialchar>[}] */
13578 int cc = c; 13578 int cc = c;
@@ -13602,11 +13602,6 @@ parsesub: {
13602 } else 13602 } else
13603 goto badsub; 13603 goto badsub;
13604 13604
13605 if (c != '}' && subtype == VSLENGTH) {
13606 /* ${#VAR didn't end with } */
13607 goto badsub;
13608 }
13609
13610 if (subtype == 0) { 13605 if (subtype == 0) {
13611 static const char types[] ALIGN1 = "}-+?="; 13606 static const char types[] ALIGN1 = "}-+?=";
13612 /* ${VAR...} but not $VAR or ${#VAR} */ 13607 /* ${VAR...} but not $VAR or ${#VAR} */
@@ -13663,6 +13658,8 @@ parsesub: {
13663#endif 13658#endif
13664 } 13659 }
13665 } else { 13660 } else {
13661 if (subtype == VSLENGTH && c != '}')
13662 subtype = 0;
13666 badsub: 13663 badsub:
13667 pungetc(); 13664 pungetc();
13668 } 13665 }
@@ -15358,7 +15355,7 @@ init(void)
15358 15355
15359 15356
15360//usage:#define ash_trivial_usage 15357//usage:#define ash_trivial_usage
15361//usage: "[-il] [-/+Cabefmnuvx] [-/+o OPT]... [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" 15358//usage: "[-il] [-|+Cabefmnuvx] [-|+o OPT]... [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]"
15362//////// comes from ^^^^^^^^^^optletters 15359//////// comes from ^^^^^^^^^^optletters
15363//usage:#define ash_full_usage "\n\n" 15360//usage:#define ash_full_usage "\n\n"
15364//usage: "Unix shell interpreter" 15361//usage: "Unix shell interpreter"
diff --git a/shell/ash_test/ash-misc/control_char3.right b/shell/ash_test/ash-misc/control_char3.right
new file mode 100644
index 000000000..283e02cbb
--- /dev/null
+++ b/shell/ash_test/ash-misc/control_char3.right
@@ -0,0 +1 @@
SHELL: line 1: : not found
diff --git a/shell/ash_test/ash-misc/control_char3.tests b/shell/ash_test/ash-misc/control_char3.tests
new file mode 100755
index 000000000..4359db3f3
--- /dev/null
+++ b/shell/ash_test/ash-misc/control_char3.tests
@@ -0,0 +1,2 @@
1# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
2$THIS_SH -c '\' SHELL
diff --git a/shell/ash_test/ash-misc/control_char4.right b/shell/ash_test/ash-misc/control_char4.right
new file mode 100644
index 000000000..2bf18e684
--- /dev/null
+++ b/shell/ash_test/ash-misc/control_char4.right
@@ -0,0 +1 @@
SHELL: line 1: -: not found
diff --git a/shell/ash_test/ash-misc/control_char4.tests b/shell/ash_test/ash-misc/control_char4.tests
new file mode 100755
index 000000000..48010f154
--- /dev/null
+++ b/shell/ash_test/ash-misc/control_char4.tests
@@ -0,0 +1,2 @@
1# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
2$THIS_SH -c '"-"' SHELL
diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.right b/shell/ash_test/ash-parsing/bkslash_newline4.right
new file mode 100644
index 000000000..2110716d1
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline4.right
@@ -0,0 +1,4 @@
11:1
222:22
33:3
4Ok:0
diff --git a/shell/ash_test/ash-parsing/bkslash_newline4.tests b/shell/ash_test/ash-parsing/bkslash_newline4.tests
new file mode 100755
index 000000000..c8f5037c4
--- /dev/null
+++ b/shell/ash_test/ash-parsing/bkslash_newline4.tests
@@ -0,0 +1,14 @@
1set -- 1 22 333
2echo 1:$\
31
4echo 22:$\
5{\
62\
7}
8echo 3:$\
9{\
10#\
113\
12}
13echo Ok:$\
14?
diff --git a/shell/hush.c b/shell/hush.c
index 77921e11c..1aa0a400d 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -339,7 +339,7 @@
339 * therefore we don't show them either. 339 * therefore we don't show them either.
340 */ 340 */
341//usage:#define hush_trivial_usage 341//usage:#define hush_trivial_usage
342//usage: "[-enxl] [-c 'SCRIPT' [ARG0 [ARGS]] / FILE [ARGS] / -s [ARGS]]" 342//usage: "[-enxl] [-c 'SCRIPT' [ARG0 ARGS] | FILE [ARGS] | -s [ARGS]]"
343//usage:#define hush_full_usage "\n\n" 343//usage:#define hush_full_usage "\n\n"
344//usage: "Unix shell interpreter" 344//usage: "Unix shell interpreter"
345 345
@@ -3696,9 +3696,10 @@ static void debug_print_tree(struct pipe *pi, int lvl)
3696 3696
3697 pin = 0; 3697 pin = 0;
3698 while (pi) { 3698 while (pi) {
3699 fdprintf(2, "%*spipe %d %sres_word=%s followup=%d %s\n", 3699 fdprintf(2, "%*spipe %d #cmds:%d %sres_word=%s followup=%d %s\n",
3700 lvl*2, "", 3700 lvl*2, "",
3701 pin, 3701 pin,
3702 pi->num_cmds,
3702 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""), 3703 (IF_HAS_KEYWORDS(pi->pi_inverted ? "! " :) ""),
3703 RES[pi->res_word], 3704 RES[pi->res_word],
3704 pi->followup, PIPE[pi->followup] 3705 pi->followup, PIPE[pi->followup]
@@ -3841,6 +3842,9 @@ static void done_pipe(struct parse_context *ctx, pipe_style type)
3841#endif 3842#endif
3842 /* Replace all pipes in ctx with one newly created */ 3843 /* Replace all pipes in ctx with one newly created */
3843 ctx->list_head = ctx->pipe = pi; 3844 ctx->list_head = ctx->pipe = pi;
3845 /* for cases like "cmd && &", do not be tricked by last command
3846 * being null - the entire {...} & is NOT null! */
3847 not_null = 1;
3844 } else { 3848 } else {
3845 no_conv: 3849 no_conv:
3846 ctx->pipe->followup = type; 3850 ctx->pipe->followup = type;
@@ -4994,6 +4998,32 @@ static int parse_dollar(o_string *as_string,
4994 * which check invalid constructs like ${%}. 4998 * which check invalid constructs like ${%}.
4995 * Oh well... let's check that the var name part is fine... */ 4999 * Oh well... let's check that the var name part is fine... */
4996 5000
5001 if (isdigit(len_single_ch)
5002 || (len_single_ch == '#' && isdigit(i_peek_and_eat_bkslash_nl(input)))
5003 ) {
5004 /* Execution engine uses plain xatoi_positive()
5005 * to interpret ${NNN} and {#NNN},
5006 * check syntax here in the parser.
5007 * (bash does not support expressions in ${#NN},
5008 * e.g. ${#$var} and {#1:+WORD} are not supported).
5009 */
5010 unsigned cnt = 9; /* max 9 digits for ${NN} and 8 for {#NN} */
5011 while (1) {
5012 o_addchr(dest, ch);
5013 debug_printf_parse(": '%c'\n", ch);
5014 ch = i_getch_and_eat_bkslash_nl(input);
5015 nommu_addchr(as_string, ch);
5016 if (ch == '}')
5017 break;
5018 if (--cnt == 0)
5019 goto bad_dollar_syntax;
5020 if (len_single_ch != '#' && strchr(VAR_SUBST_OPS, ch))
5021 /* ${NN<op>...} is valid */
5022 goto eat_until_closing;
5023 if (!isdigit(ch))
5024 goto bad_dollar_syntax;
5025 }
5026 } else
4997 while (1) { 5027 while (1) {
4998 unsigned pos; 5028 unsigned pos;
4999 5029
@@ -5004,7 +5034,6 @@ static int parse_dollar(o_string *as_string,
5004 nommu_addchr(as_string, ch); 5034 nommu_addchr(as_string, ch);
5005 if (ch == '}') 5035 if (ch == '}')
5006 break; 5036 break;
5007
5008 if (!isalnum(ch) && ch != '_') { 5037 if (!isalnum(ch) && ch != '_') {
5009 unsigned end_ch; 5038 unsigned end_ch;
5010 unsigned char last_ch; 5039 unsigned char last_ch;
@@ -5023,6 +5052,7 @@ static int parse_dollar(o_string *as_string,
5023 * special var name, e.g. ${#!}. 5052 * special var name, e.g. ${#!}.
5024 */ 5053 */
5025 } 5054 }
5055 eat_until_closing:
5026 /* Eat everything until closing '}' (or ':') */ 5056 /* Eat everything until closing '}' (or ':') */
5027 end_ch = '}'; 5057 end_ch = '}';
5028 if (BASH_SUBSTR 5058 if (BASH_SUBSTR
@@ -5237,6 +5267,11 @@ static int encode_string(o_string *as_string,
5237 } 5267 }
5238#endif 5268#endif
5239 o_addQchr(dest, ch); 5269 o_addQchr(dest, ch);
5270 if (ch == SPECIAL_VAR_SYMBOL) {
5271 /* Convert "^C" to corresponding special variable reference */
5272 o_addchr(dest, SPECIAL_VAR_QUOTED_SVS);
5273 o_addchr(dest, SPECIAL_VAR_SYMBOL);
5274 }
5240 goto again; 5275 goto again;
5241#undef as_string 5276#undef as_string
5242} 5277}
@@ -5348,6 +5383,11 @@ static struct pipe *parse_stream(char **pstring,
5348 if (ch == '\n') 5383 if (ch == '\n')
5349 continue; /* drop \<newline>, get next char */ 5384 continue; /* drop \<newline>, get next char */
5350 nommu_addchr(&ctx.as_string, '\\'); 5385 nommu_addchr(&ctx.as_string, '\\');
5386 if (ch == SPECIAL_VAR_SYMBOL) {
5387 nommu_addchr(&ctx.as_string, ch);
5388 /* Convert \^C to corresponding special variable reference */
5389 goto case_SPECIAL_VAR_SYMBOL;
5390 }
5351 o_addchr(&ctx.word, '\\'); 5391 o_addchr(&ctx.word, '\\');
5352 if (ch == EOF) { 5392 if (ch == EOF) {
5353 /* Testcase: eval 'echo Ok\' */ 5393 /* Testcase: eval 'echo Ok\' */
@@ -5672,6 +5712,7 @@ static struct pipe *parse_stream(char **pstring,
5672 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */ 5712 /* Note: nommu_addchr(&ctx.as_string, ch) is already done */
5673 5713
5674 switch (ch) { 5714 switch (ch) {
5715 case_SPECIAL_VAR_SYMBOL:
5675 case SPECIAL_VAR_SYMBOL: 5716 case SPECIAL_VAR_SYMBOL:
5676 /* Convert raw ^C to corresponding special variable reference */ 5717 /* Convert raw ^C to corresponding special variable reference */
5677 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL); 5718 o_addchr(&ctx.word, SPECIAL_VAR_SYMBOL);
diff --git a/shell/hush_test/hush-misc/control_char3.right b/shell/hush_test/hush-misc/control_char3.right
new file mode 100644
index 000000000..94b4f8699
--- /dev/null
+++ b/shell/hush_test/hush-misc/control_char3.right
@@ -0,0 +1 @@
hush: can't execute '': No such file or directory
diff --git a/shell/hush_test/hush-misc/control_char3.tests b/shell/hush_test/hush-misc/control_char3.tests
new file mode 100755
index 000000000..4359db3f3
--- /dev/null
+++ b/shell/hush_test/hush-misc/control_char3.tests
@@ -0,0 +1,2 @@
1# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
2$THIS_SH -c '\' SHELL
diff --git a/shell/hush_test/hush-misc/control_char4.right b/shell/hush_test/hush-misc/control_char4.right
new file mode 100644
index 000000000..698e21427
--- /dev/null
+++ b/shell/hush_test/hush-misc/control_char4.right
@@ -0,0 +1 @@
hush: can't execute '-': No such file or directory
diff --git a/shell/hush_test/hush-misc/control_char4.tests b/shell/hush_test/hush-misc/control_char4.tests
new file mode 100755
index 000000000..48010f154
--- /dev/null
+++ b/shell/hush_test/hush-misc/control_char4.tests
@@ -0,0 +1,2 @@
1# (set argv0 to "SHELL" to avoid "/path/to/shell: blah" in error messages)
2$THIS_SH -c '"-"' SHELL
diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.right b/shell/hush_test/hush-parsing/bkslash_newline4.right
new file mode 100644
index 000000000..2110716d1
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline4.right
@@ -0,0 +1,4 @@
11:1
222:22
33:3
4Ok:0
diff --git a/shell/hush_test/hush-parsing/bkslash_newline4.tests b/shell/hush_test/hush-parsing/bkslash_newline4.tests
new file mode 100755
index 000000000..c8f5037c4
--- /dev/null
+++ b/shell/hush_test/hush-parsing/bkslash_newline4.tests
@@ -0,0 +1,14 @@
1set -- 1 22 333
2echo 1:$\
31
4echo 22:$\
5{\
62\
7}
8echo 3:$\
9{\
10#\
113\
12}
13echo Ok:$\
14?
diff --git a/shell/hush_test/hush-vars/var6.right b/shell/hush_test/hush-vars/var6.right
index 40e67fdf5..5e28d2fab 100644
--- a/shell/hush_test/hush-vars/var6.right
+++ b/shell/hush_test/hush-vars/var6.right
@@ -1,2 +1,2 @@
1hush: invalid number '1q' 1hush: syntax error: unterminated ${name}
2hush: syntax error: unterminated ${name} 2hush: syntax error: unterminated ${name}