diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-16 10:39:24 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-05-16 10:39:24 +0000 |
commit | 1f4cf517f5803b0e300906c487d365a331122091 (patch) | |
tree | 8ca30e71e1c0d7cb6f3b64fd9911a85c615170e8 | |
parent | 8f6bdb42df745425ba0ac085467105e9cc61c817 (diff) | |
download | busybox-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.c | 45 | ||||
-rw-r--r-- | shell/hush_test/hush-bugs/quote3.right | 5 | ||||
-rwxr-xr-x | shell/hush_test/hush-bugs/quote3.tests | 4 | ||||
-rw-r--r-- | shell/hush_test/hush-bugs/starquoted.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-bugs/starquoted.tests | 4 | ||||
-rw-r--r-- | shell/hush_test/hush-parsing/quote4.right | 1 | ||||
-rwxr-xr-x | shell/hush_test/hush-parsing/quote4.tests | 2 | ||||
-rw-r--r-- | shell/hush_test/hush-parsing/starquoted.right | 8 | ||||
-rwxr-xr-x | shell/hush_test/hush-parsing/starquoted.tests | 8 |
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) | |||
2425 | static int expand_vars_to_list(char **list, int n, char **posp, char *arg) | 2425 | static 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 */ |
3269 | static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input) | 3287 | static 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 @@ | |||
1 | Testing: in $empty"" | 1 | Testing: in $empty"" |
2 | .. | 2 | .. |
3 | Testing: in "$*" | ||
4 | .abc d e. | ||
5 | Testing: in "$@" | ||
6 | .abc. | ||
7 | .d e. | ||
8 | Finished | 3 | Finished |
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 | |||
5 | echo 'Testing: in $empty""' | 5 | echo 'Testing: in $empty""' |
6 | empty='' | 6 | empty='' |
7 | for a in $empty""; do echo ".$a."; done | 7 | for a in $empty""; do echo ".$a."; done |
8 | echo 'Testing: in "$*"' | ||
9 | for a in "$*"; do echo ".$a."; done | ||
10 | echo 'Testing: in "$@"' | ||
11 | for a in "$@"; do echo ".$a."; done | ||
12 | echo Finished | 8 | echo 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 @@ | |||
1 | if test $# = 0; then | ||
2 | exec "$THIS_SH" starquoted.tests 1 abc 'd e f' | ||
3 | fi | ||
4 | for 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 @@ | |||
1 | a_b='a b' | ||
2 | echo "$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 @@ | |||
1 | if test $# = 0; then | ||
2 | exec "$THIS_SH" "$0" 1 abc 'd e f' | ||
3 | fi | ||
4 | |||
5 | for a in "$*"; do echo ".$a."; done | ||
6 | for a in "$@"; do echo ".$a."; done | ||
7 | for a in "-$*-"; do echo ".$a."; done | ||
8 | for a in "-$@-"; do echo ".$a."; done | ||