aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-05-16 10:39:24 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-05-16 10:39:24 +0000
commit1f4cf517f5803b0e300906c487d365a331122091 (patch)
tree8ca30e71e1c0d7cb6f3b64fd9911a85c615170e8
parent8f6bdb42df745425ba0ac085467105e9cc61c817 (diff)
downloadbusybox-w32-1f4cf517f5803b0e300906c487d365a331122091.tar.gz
busybox-w32-1f4cf517f5803b0e300906c487d365a331122091.tar.bz2
busybox-w32-1f4cf517f5803b0e300906c487d365a331122091.zip
hush: fix expansion of quoted $VAR, $* and $@
-rw-r--r--shell/hush.c45
-rw-r--r--shell/hush_test/hush-bugs/quote3.right5
-rwxr-xr-xshell/hush_test/hush-bugs/quote3.tests4
-rw-r--r--shell/hush_test/hush-bugs/starquoted.right1
-rwxr-xr-xshell/hush_test/hush-bugs/starquoted.tests4
-rw-r--r--shell/hush_test/hush-parsing/quote4.right1
-rwxr-xr-xshell/hush_test/hush-parsing/quote4.tests2
-rw-r--r--shell/hush_test/hush-parsing/starquoted.right8
-rwxr-xr-xshell/hush_test/hush-parsing/starquoted.tests8
9 files changed, 51 insertions, 27 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e49c0c989..e3dd6663e 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -2425,6 +2425,7 @@ static int expand_on_ifs(char **list, int n, char **posp, const char *str)
2425static int expand_vars_to_list(char **list, int n, char **posp, char *arg) 2425static int expand_vars_to_list(char **list, int n, char **posp, char *arg)
2426{ 2426{
2427 char first_ch, ored_ch; 2427 char first_ch, ored_ch;
2428 int i;
2428 const char *val; 2429 const char *val;
2429 char *p; 2430 char *p;
2430 char *pos = *posp; 2431 char *pos = *posp;
@@ -2462,8 +2463,8 @@ static int expand_vars_to_list(char **list, int n, char **posp, char *arg)
2462 break; 2463 break;
2463 case '*': 2464 case '*':
2464 case '@': 2465 case '@':
2466 i = 1;
2465 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */ 2467 if (!(first_ch & 0x80)) { /* unquoted $* or $@ */
2466 int i = 1;
2467 while (i < global_argc) { 2468 while (i < global_argc) {
2468 n = expand_on_ifs(list, n, &pos, global_argv[i]); 2469 n = expand_on_ifs(list, n, &pos, global_argv[i]);
2469 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, global_argc-1); 2470 debug_printf_expand("expand_vars_to_list: argv %d (last %d)\n", i, global_argc-1);
@@ -2478,16 +2479,33 @@ static int expand_vars_to_list(char **list, int n, char **posp, char *arg)
2478 } 2479 }
2479 } 2480 }
2480 } else if (first_ch == ('@'|0x80)) { /* quoted $@ */ 2481 } else if (first_ch == ('@'|0x80)) { /* quoted $@ */
2481 /* TODO */ 2482 while (1) {
2482 } else { /* quoted $* */ 2483 strcpy(pos, global_argv[i]);
2483 /* TODO */ 2484 pos += strlen(global_argv[i]);
2485 if (++i >= global_argc)
2486 break;
2487 *pos++ = '\0';
2488 if (n) debug_printf_expand("expand_vars_to_list 3 finalized list[%d]=%p '%s' "
2489 "strlen=%d next=%p pos=%p\n", n-1, list[n-1], list[n-1],
2490 strlen(list[n-1]), list[n-1] + strlen(list[n-1]) + 1, pos);
2491 list[n++] = pos;
2492 }
2493 } else { /* quoted $*: add as one word */
2494 while (1) {
2495 strcpy(pos, global_argv[i]);
2496 pos += strlen(global_argv[i]);
2497 if (++i >= global_argc)
2498 break;
2499 if (ifs[0])
2500 *pos++ = ifs[0];
2501 }
2484 } 2502 }
2485 break; 2503 break;
2486 default: 2504 default:
2487 *p = '\0'; 2505 *p = '\0';
2488 arg[0] = first_ch & 0x7f; 2506 arg[0] = first_ch & 0x7f;
2489 if (isdigit(arg[0])) { 2507 if (isdigit(arg[0])) {
2490 int i = xatoi_u(arg); 2508 i = xatoi_u(arg);
2491 val = NULL; 2509 val = NULL;
2492 if (i < global_argc) 2510 if (i < global_argc)
2493 val = global_argv[i]; 2511 val = global_argv[i];
@@ -2495,12 +2513,12 @@ static int expand_vars_to_list(char **list, int n, char **posp, char *arg)
2495 val = lookup_param(arg); 2513 val = lookup_param(arg);
2496 arg[0] = first_ch; 2514 arg[0] = first_ch;
2497 *p = SPECIAL_VAR_SYMBOL; 2515 *p = SPECIAL_VAR_SYMBOL;
2498 if (!(first_ch & 0x80)) { /* unquoted var */ 2516 if (!(first_ch & 0x80)) { /* unquoted $VAR */
2499 if (val) { 2517 if (val) {
2500 n = expand_on_ifs(list, n, &pos, val); 2518 n = expand_on_ifs(list, n, &pos, val);
2501 val = NULL; 2519 val = NULL;
2502 } 2520 }
2503 } 2521 } /* else: quoted $VAR, val will be appended at pos */
2504 } 2522 }
2505 if (val) { 2523 if (val) {
2506 strcpy(pos, val); 2524 strcpy(pos, val);
@@ -3268,18 +3286,18 @@ static char* make_string(char **inp)
3268/* return code: 0 for OK, 1 for syntax error */ 3286/* return code: 0 for OK, 1 for syntax error */
3269static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) 3287static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input)
3270{ 3288{
3271// int i;
3272// char sep[] = " ";
3273 int ch = b_peek(input); /* first character after the $ */ 3289 int ch = b_peek(input); /* first character after the $ */
3290 unsigned char quote_mask = dest->quote ? 0x80 : 0;
3274 3291
3275 debug_printf_parse("handle_dollar entered: ch='%c'\n", ch); 3292 debug_printf_parse("handle_dollar entered: ch='%c'\n", ch);
3276 if (isalpha(ch) || ch == '?') { 3293 if (isalpha(ch)) {
3277 b_addchr(dest, SPECIAL_VAR_SYMBOL); 3294 b_addchr(dest, SPECIAL_VAR_SYMBOL);
3278 ctx->child->sp++; 3295 ctx->child->sp++;
3279 while (1) { 3296 while (1) {
3280 debug_printf_parse(": '%c'\n", ch); 3297 debug_printf_parse(": '%c'\n", ch);
3281 b_getch(input); 3298 b_getch(input);
3282 b_addchr(dest, ch); 3299 b_addchr(dest, ch | quote_mask);
3300 quote_mask = 0;
3283 ch = b_peek(input); 3301 ch = b_peek(input);
3284 if (!isalnum(ch) && ch != '_') 3302 if (!isalnum(ch) && ch != '_')
3285 break; 3303 break;
@@ -3291,7 +3309,7 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
3291 ctx->child->sp++; 3309 ctx->child->sp++;
3292 debug_printf_parse(": '%c'\n", ch); 3310 debug_printf_parse(": '%c'\n", ch);
3293 b_getch(input); 3311 b_getch(input);
3294 b_addchr(dest, ch); 3312 b_addchr(dest, ch | quote_mask);
3295 b_addchr(dest, SPECIAL_VAR_SYMBOL); 3313 b_addchr(dest, SPECIAL_VAR_SYMBOL);
3296 } else switch (ch) { 3314 } else switch (ch) {
3297 case '$': /* pid */ 3315 case '$': /* pid */
@@ -3316,7 +3334,8 @@ static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *i
3316 if (ch == '}') 3334 if (ch == '}')
3317 break; 3335 break;
3318 debug_printf_parse(": '%c'\n", ch); 3336 debug_printf_parse(": '%c'\n", ch);
3319 b_addchr(dest, ch); 3337 b_addchr(dest, ch | quote_mask);
3338 quote_mask = 0;
3320 } 3339 }
3321 b_addchr(dest, SPECIAL_VAR_SYMBOL); 3340 b_addchr(dest, SPECIAL_VAR_SYMBOL);
3322 break; 3341 break;
diff --git a/shell/hush_test/hush-bugs/quote3.right b/shell/hush_test/hush-bugs/quote3.right
index 11443f54b..069a46e8f 100644
--- a/shell/hush_test/hush-bugs/quote3.right
+++ b/shell/hush_test/hush-bugs/quote3.right
@@ -1,8 +1,3 @@
1Testing: in $empty"" 1Testing: in $empty""
2.. 2..
3Testing: in "$*"
4.abc d e.
5Testing: in "$@"
6.abc.
7.d e.
8Finished 3Finished
diff --git a/shell/hush_test/hush-bugs/quote3.tests b/shell/hush_test/hush-bugs/quote3.tests
index c52e040cc..075e78570 100755
--- a/shell/hush_test/hush-bugs/quote3.tests
+++ b/shell/hush_test/hush-bugs/quote3.tests
@@ -5,8 +5,4 @@ fi
5echo 'Testing: in $empty""' 5echo 'Testing: in $empty""'
6empty='' 6empty=''
7for a in $empty""; do echo ".$a."; done 7for a in $empty""; do echo ".$a."; done
8echo 'Testing: in "$*"'
9for a in "$*"; do echo ".$a."; done
10echo 'Testing: in "$@"'
11for a in "$@"; do echo ".$a."; done
12echo Finished 8echo Finished
diff --git a/shell/hush_test/hush-bugs/starquoted.right b/shell/hush_test/hush-bugs/starquoted.right
deleted file mode 100644
index fedaf4805..000000000
--- a/shell/hush_test/hush-bugs/starquoted.right
+++ /dev/null
@@ -1 +0,0 @@
1.1 abc d e f.
diff --git a/shell/hush_test/hush-bugs/starquoted.tests b/shell/hush_test/hush-bugs/starquoted.tests
deleted file mode 100755
index 3be2026b7..000000000
--- a/shell/hush_test/hush-bugs/starquoted.tests
+++ /dev/null
@@ -1,4 +0,0 @@
1if test $# = 0; then
2 exec "$THIS_SH" starquoted.tests 1 abc 'd e f'
3fi
4for a in "$*"; do echo ".$a."; done
diff --git a/shell/hush_test/hush-parsing/quote4.right b/shell/hush_test/hush-parsing/quote4.right
new file mode 100644
index 000000000..b2901ea97
--- /dev/null
+++ b/shell/hush_test/hush-parsing/quote4.right
@@ -0,0 +1 @@
a b
diff --git a/shell/hush_test/hush-parsing/quote4.tests b/shell/hush_test/hush-parsing/quote4.tests
new file mode 100755
index 000000000..f1dabfa54
--- /dev/null
+++ b/shell/hush_test/hush-parsing/quote4.tests
@@ -0,0 +1,2 @@
1a_b='a b'
2echo "$a_b"
diff --git a/shell/hush_test/hush-parsing/starquoted.right b/shell/hush_test/hush-parsing/starquoted.right
new file mode 100644
index 000000000..b56323fe1
--- /dev/null
+++ b/shell/hush_test/hush-parsing/starquoted.right
@@ -0,0 +1,8 @@
1.1 abc d e f.
2.1.
3.abc.
4.d e f.
5.-1 abc d e f-.
6.-1.
7.abc.
8.d e f-.
diff --git a/shell/hush_test/hush-parsing/starquoted.tests b/shell/hush_test/hush-parsing/starquoted.tests
new file mode 100755
index 000000000..2fe49b1cd
--- /dev/null
+++ b/shell/hush_test/hush-parsing/starquoted.tests
@@ -0,0 +1,8 @@
1if test $# = 0; then
2 exec "$THIS_SH" "$0" 1 abc 'd e f'
3fi
4
5for a in "$*"; do echo ".$a."; done
6for a in "$@"; do echo ".$a."; done
7for a in "-$*-"; do echo ".$a."; done
8for a in "-$@-"; do echo ".$a."; done