aboutsummaryrefslogtreecommitdiff
path: root/shell/hush.c
diff options
context:
space:
mode:
authorDenys Vlasenko <dvlasenk@redhat.com>2010-09-04 19:52:44 +0200
committerDenys Vlasenko <dvlasenk@redhat.com>2010-09-04 19:52:44 +0200
commite298ce69baef029f3951dd1d5ed50fdbc6c55c80 (patch)
tree85060a1578474d8ca4e1d5f89e1b0c8241235ba5 /shell/hush.c
parent8ae6e9be5c1c7e7a1e9ce96f463c7d6ab1c9500f (diff)
downloadbusybox-w32-e298ce69baef029f3951dd1d5ed50fdbc6c55c80.tar.gz
busybox-w32-e298ce69baef029f3951dd1d5ed50fdbc6c55c80.tar.bz2
busybox-w32-e298ce69baef029f3951dd1d5ed50fdbc6c55c80.zip
hush: fix handling of backslashes in variable assignment
Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
Diffstat (limited to 'shell/hush.c')
-rw-r--r--shell/hush.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/shell/hush.c b/shell/hush.c
index e8dfb2499..d3dab5863 100644
--- a/shell/hush.c
+++ b/shell/hush.c
@@ -390,6 +390,7 @@ typedef struct o_string {
390 smallint o_glob; 390 smallint o_glob;
391 /* At least some part of the string was inside '' or "", 391 /* At least some part of the string was inside '' or "",
392 * possibly empty one: word"", wo''rd etc. */ 392 * possibly empty one: word"", wo''rd etc. */
393//TODO: rename to no_empty_expansion?
393 smallint o_quoted; 394 smallint o_quoted;
394 smallint has_empty_slot; 395 smallint has_empty_slot;
395 smallint o_assignment; /* 0:maybe, 1:yes, 2:no */ 396 smallint o_assignment; /* 0:maybe, 1:yes, 2:no */
@@ -2018,11 +2019,10 @@ static void o_addblock_duplicate_backslash(o_string *o, const char *str, int len
2018{ 2019{
2019 while (len) { 2020 while (len) {
2020 o_addchr(o, *str); 2021 o_addchr(o, *str);
2021 if (*str++ == '\\' 2022 if (*str == '\\') {
2022 && (*str != '*' && *str != '?' && *str != '[')
2023 ) {
2024 o_addchr(o, '\\'); 2023 o_addchr(o, '\\');
2025 } 2024 }
2025 str++;
2026 len--; 2026 len--;
2027 } 2027 }
2028} 2028}
@@ -2128,8 +2128,8 @@ static void debug_print_list(const char *prefix, o_string *o, int n)
2128 int i = 0; 2128 int i = 0;
2129 2129
2130 indent(); 2130 indent();
2131 fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d\n", 2131 fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
2132 prefix, list, n, string_start, o->length, o->maxlen); 2132 prefix, list, n, string_start, o->length, o->maxlen, o->o_glob, o->o_quoted, o->o_escape);
2133 while (i < n) { 2133 while (i < n) {
2134 indent(); 2134 indent();
2135 fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i], 2135 fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i],
@@ -2563,9 +2563,9 @@ static char *expand_pseudo_dquoted(const char *str)
2563 struct in_str input; 2563 struct in_str input;
2564 o_string dest = NULL_O_STRING; 2564 o_string dest = NULL_O_STRING;
2565 2565
2566 if (strchr(str, '$') == NULL 2566 if (!strchr(str, '$')
2567#if ENABLE_HUSH_TICK 2567#if ENABLE_HUSH_TICK
2568 && strchr(str, '`') == NULL 2568 && !strchr(str, '`')
2569#endif 2569#endif
2570 ) { 2570 ) {
2571 return NULL; 2571 return NULL;
@@ -2740,6 +2740,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
2740 } 2740 }
2741#endif 2741#endif
2742 default: { /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */ 2742 default: { /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
2743//TODO: move to a subroutine?
2743 char *var; 2744 char *var;
2744 char first_char; 2745 char first_char;
2745 char exp_op; 2746 char exp_op;
@@ -3000,18 +3001,22 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
3000 return n; 3001 return n;
3001} 3002}
3002 3003
3003static char **expand_variables(char **argv, int or_mask) 3004enum {
3005 EXPVAR_FLAG_GLOB = 0x200,
3006 EXPVAR_FLAG_ESCAPE_VARS = 0x100,
3007 EXPVAR_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */
3008};
3009static char **expand_variables(char **argv, unsigned or_mask)
3004{ 3010{
3005 int n; 3011 int n;
3006 char **list; 3012 char **list;
3007 char **v; 3013 char **v;
3008 o_string output = NULL_O_STRING; 3014 o_string output = NULL_O_STRING;
3009 3015
3010 if (or_mask & 0x100) { 3016 /* protect against globbing for "$var"? */
3011 output.o_escape = 1; /* protect against globbing for "$var" */ 3017 /* (unquoted $var will temporarily switch it off) */
3012 /* (unquoted $var will temporarily switch it off) */ 3018 output.o_escape = 1 & (or_mask / EXPVAR_FLAG_ESCAPE_VARS);
3013 output.o_glob = 1; 3019 output.o_glob = 1 & (or_mask / EXPVAR_FLAG_GLOB);
3014 }
3015 3020
3016 n = 0; 3021 n = 0;
3017 v = argv; 3022 v = argv;
@@ -3029,13 +3034,13 @@ static char **expand_variables(char **argv, int or_mask)
3029 3034
3030static char **expand_strvec_to_strvec(char **argv) 3035static char **expand_strvec_to_strvec(char **argv)
3031{ 3036{
3032 return expand_variables(argv, 0x100); 3037 return expand_variables(argv, EXPVAR_FLAG_GLOB | EXPVAR_FLAG_ESCAPE_VARS);
3033} 3038}
3034 3039
3035#if ENABLE_HUSH_BASH_COMPAT 3040#if ENABLE_HUSH_BASH_COMPAT
3036static char **expand_strvec_to_strvec_singleword_noglob(char **argv) 3041static char **expand_strvec_to_strvec_singleword_noglob(char **argv)
3037{ 3042{
3038 return expand_variables(argv, 0x80); 3043 return expand_variables(argv, EXPVAR_FLAG_SINGLEWORD);
3039} 3044}
3040#endif 3045#endif
3041 3046
@@ -3075,15 +3080,15 @@ static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv)
3075#endif 3080#endif
3076 3081
3077/* Used for expansion of right hand of assignments */ 3082/* Used for expansion of right hand of assignments */
3078/* NB: should NOT do globbing! "export v=/bin/c*; env | grep ^v=" outputs 3083/* NB: should NOT do globbing!
3079 * "v=/bin/c*" */ 3084 * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*" */
3080static char *expand_string_to_string(const char *str) 3085static char *expand_string_to_string(const char *str)
3081{ 3086{
3082 char *argv[2], **list; 3087 char *argv[2], **list;
3083 3088
3084 argv[0] = (char*)str; 3089 argv[0] = (char*)str;
3085 argv[1] = NULL; 3090 argv[1] = NULL;
3086 list = expand_variables(argv, 0x80); /* 0x80: singleword expansion */ 3091 list = expand_variables(argv, EXPVAR_FLAG_ESCAPE_VARS | EXPVAR_FLAG_SINGLEWORD);
3087 if (HUSH_DEBUG) 3092 if (HUSH_DEBUG)
3088 if (!list[0] || list[1]) 3093 if (!list[0] || list[1])
3089 bb_error_msg_and_die("BUG in varexp2"); 3094 bb_error_msg_and_die("BUG in varexp2");
@@ -3099,7 +3104,7 @@ static char* expand_strvec_to_string(char **argv)
3099{ 3104{
3100 char **list; 3105 char **list;
3101 3106
3102 list = expand_variables(argv, 0x80); 3107 list = expand_variables(argv, EXPVAR_FLAG_SINGLEWORD);
3103 /* Convert all NULs to spaces */ 3108 /* Convert all NULs to spaces */
3104 if (list[0]) { 3109 if (list[0]) {
3105 int n = 1; 3110 int n = 1;