summaryrefslogtreecommitdiffhomepage
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)
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 {
smallint o_glob;
/* At least some part of the string was inside '' or "",
* possibly empty one: word"", wo''rd etc. */
+//TODO: rename to no_empty_expansion?
smallint o_quoted;
smallint has_empty_slot;
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
{
while (len) {
o_addchr(o, *str);
- if (*str++ == '\\'
- && (*str != '*' && *str != '?' && *str != '[')
- ) {
+ if (*str == '\\') {
o_addchr(o, '\\');
}
+ str++;
len--;
}
}
@@ -2128,8 +2128,8 @@ static void debug_print_list(const char *prefix, o_string *o, int n)
int i = 0;
indent();
- fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d\n",
- prefix, list, n, string_start, o->length, o->maxlen);
+ fprintf(stderr, "%s: list:%p n:%d string_start:%d length:%d maxlen:%d glob:%d quoted:%d escape:%d\n",
+ prefix, list, n, string_start, o->length, o->maxlen, o->o_glob, o->o_quoted, o->o_escape);
while (i < n) {
indent();
fprintf(stderr, " list[%d]=%d '%s' %p\n", i, (int)list[i],
@@ -2563,9 +2563,9 @@ static char *expand_pseudo_dquoted(const char *str)
struct in_str input;
o_string dest = NULL_O_STRING;
- if (strchr(str, '$') == NULL
+ if (!strchr(str, '$')
#if ENABLE_HUSH_TICK
- && strchr(str, '`') == NULL
+ && !strchr(str, '`')
#endif
) {
return NULL;
@@ -2740,6 +2740,7 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
}
#endif
default: { /* <SPECIAL_VAR_SYMBOL>varname<SPECIAL_VAR_SYMBOL> */
+//TODO: move to a subroutine?
char *var;
char first_char;
char exp_op;
@@ -3000,18 +3001,22 @@ static NOINLINE int expand_vars_to_list(o_string *output, int n, char *arg, char
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;
@@ -3029,13 +3034,13 @@ static char **expand_variables(char **argv, int or_mask)
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
@@ -3075,15 +3080,15 @@ static char **expand_strvec_to_strvec_singleword_noglob_cond(char **argv)
#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");
@@ -3099,7 +3104,7 @@ static char* expand_strvec_to_string(char **argv)
{
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;