--- a/shell/hush.c +++ b/shell/hush.c @@ -1853,7 +1853,7 @@ static void o_addblock_duplicate_backsla while (len) { o_addchr(o, *str); if (*str++ == '\\' - && (*str != '*' && *str != '?' && *str != '[') +// && (*str != '*' && *str != '?' && *str != '[') ) { o_addchr(o, '\\'); } @@ -2834,18 +2834,22 @@ static NOINLINE int expand_vars_to_list( return n; } -static char **expand_variables(char **argv, int or_mask) +enum { + EXPVAR_FLAG_GLOB = 0x200, + EXPVAR_FLAG_ESCAPE_VARS = 0x100, + EXPVAR_FLAG_SINGLEWORD = 0x80, /* must be 0x80 */ +}; +static char **expand_variables(char **argv, unsigned or_mask) { int n; char **list; char **v; o_string output = NULL_O_STRING; - if (or_mask & 0x100) { - output.o_escape = 1; /* protect against globbing for "$var" */ - /* (unquoted $var will temporarily switch it off) */ - output.o_glob = 1; - } + /* protect against globbing for "$var"? */ + /* (unquoted $var will temporarily switch it off) */ + output.o_escape = 1 & (or_mask / EXPVAR_FLAG_ESCAPE_VARS); + output.o_glob = 1 & (or_mask / EXPVAR_FLAG_GLOB); n = 0; v = argv; @@ -2863,13 +2867,13 @@ static char **expand_variables(char **ar static char **expand_strvec_to_strvec(char **argv) { - return expand_variables(argv, 0x100); + return expand_variables(argv, EXPVAR_FLAG_GLOB | EXPVAR_FLAG_ESCAPE_VARS); } #if ENABLE_HUSH_BASH_COMPAT static char **expand_strvec_to_strvec_singleword_noglob(char **argv) { - return expand_variables(argv, 0x80); + return expand_variables(argv, EXPVAR_FLAG_SINGLEWORD); } #endif @@ -2909,15 +2913,15 @@ static char **expand_strvec_to_strvec_si #endif /* Used for expansion of right hand of assignments */ -/* NB: should NOT do globbing! "export v=/bin/c*; env | grep ^v=" outputs - * "v=/bin/c*" */ +/* NB: should NOT do globbing! + * "export v=/bin/c*; env | grep ^v=" outputs "v=/bin/c*" */ static char *expand_string_to_string(const char *str) { char *argv[2], **list; argv[0] = (char*)str; argv[1] = NULL; - list = expand_variables(argv, 0x80); /* 0x80: singleword expansion */ + list = expand_variables(argv, EXPVAR_FLAG_ESCAPE_VARS | EXPVAR_FLAG_SINGLEWORD); if (HUSH_DEBUG) if (!list[0] || list[1]) bb_error_msg_and_die("BUG in varexp2"); @@ -2933,7 +2937,7 @@ static char* expand_strvec_to_string(cha { char **list; - list = expand_variables(argv, 0x80); + list = expand_variables(argv, EXPVAR_FLAG_SINGLEWORD); /* Convert all NULs to spaces */ if (list[0]) { int n = 1; --- /dev/null +++ b/shell/hush_test/hush-vars/var_unbackslash.right @@ -0,0 +1,9 @@ +b1=-qwerty-t-\-"---z-*-?- +b1=-qwerty-t-\-"---z-*-?- +b2=-$a-\t-\\-\"-\--\z-\*-\?- +b2=-$a-\t-\\-\"-\--\z-\*-\?- +c=-$a-\t-\\-\"-\--\z-\*-\?- +c=-$a-\t-\\-\"-\--\z-\*-\?- +c=-$a-\t-\\-\"-\--\z-\*-\?- +c=-$a-\t-\\-\"-\--\z-\*-\?- +Done: 0 --- /dev/null +++ b/shell/hush_test/hush-vars/var_unbackslash.tests @@ -0,0 +1,20 @@ +# Test for correct handling of backslashes +a=qwerty + +b=-$a-\t-\\-\"-\--\z-\*-\?- +echo b1=$b +echo "b1=$b" +b='-$a-\t-\\-\"-\--\z-\*-\?-' +echo b2=$b +echo "b2=$b" + +c=$b +echo "c=$c" +c=${b} +echo "c=$c" +c="$b" +echo "c=$c" +c="${b}" +echo "c=$c" + +echo "Done: $?"