]> git.kernelconcepts.de Git - karo-tx-uboot.git/blobdiff - common/hush.c
hush: fix some quoted variable expansion issues
[karo-tx-uboot.git] / common / hush.c
index 3f3a79c5084209acf6ab0528ca71a73343ec7f70..df10267d644257476fdcad5b22ec1f5d3246cdc6 100644 (file)
@@ -221,6 +221,8 @@ struct child_prog {
        pid_t pid;                                      /* 0 if exited */
 #endif
        char **argv;                            /* program name and arguments */
+       /* was quoted when parsed; copy of struct o_string.nonnull field */
+       int *argv_nonnull;                      
 #ifdef __U_BOOT__
        int    argc;                            /* number of program arguments */
 #endif
@@ -467,7 +469,7 @@ static int process_command_subs(o_string *dest, struct p_context *ctx, struct in
 static int parse_group(o_string *dest, struct p_context *ctx, struct in_str *input, int ch);
 #endif
 static char *lookup_param(char *src);
-static char *make_string(char **inp);
+static char *make_string(char **inp, int *nonnull);
 static int handle_dollar(o_string *dest, struct p_context *ctx, struct in_str *input);
 #ifndef __U_BOOT__
 static int parse_string(o_string *dest, struct p_context *ctx, const char *src);
@@ -1613,7 +1615,8 @@ static int run_pipe_real(struct pipe *pi)
                if (child->sp) {
                        char * str = NULL;
 
-                       str = make_string((child->argv + i));
+                       str = make_string(child->argv + i,
+                                         child->argv_nonnull + i);
                        parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING);
                        free(str);
                        return last_return_code;
@@ -1940,7 +1943,8 @@ static int free_pipe(struct pipe *pi, int indent)
                        for (a = 0; a < child->argc; a++) {
                                free(child->argv[a]);
                        }
-                                       free(child->argv);
+                       free(child->argv);
+                       free(child->argv_nonnull);
                        child->argc = 0;
 #endif
                        child->argv=NULL;
@@ -2470,8 +2474,14 @@ static int done_word(o_string *dest, struct p_context *ctx)
                argc = ++child->argc;
                child->argv = realloc(child->argv, (argc+1)*sizeof(*child->argv));
                if (child->argv == NULL) return 1;
+               child->argv_nonnull = realloc(child->argv_nonnull,
+                                       (argc+1)*sizeof(*child->argv_nonnull));
+               if (child->argv_nonnull == NULL)
+                       return 1;
                child->argv[argc-1]=str;
+               child->argv_nonnull[argc-1] = dest->nonnull;
                child->argv[argc]=NULL;
+               child->argv_nonnull[argc] = 0;
                for (s = dest->data; s && *s; s++,str++) {
                        if (*s == '\\') s++;
                        *str = *s;
@@ -2537,6 +2547,7 @@ static int done_command(struct p_context *ctx)
        prog->redirects = NULL;
 #endif
        prog->argv = NULL;
+       prog->argv_nonnull = NULL;
 #ifndef __U_BOOT__
        prog->is_stopped = 0;
 #endif
@@ -3585,8 +3596,12 @@ static char **make_list_in(char **inp, char *name)
        return list;
 }
 
-/* Make new string for parser */
-static char * make_string(char ** inp)
+/*
+ * Make new string for parser
+ * inp     - array of argument strings to flatten
+ * nonnull - indicates argument was quoted when originally parsed
+ */
+static char *make_string(char **inp, int *nonnull)
 {
        char *p;
        char *str = NULL;
@@ -3600,13 +3615,17 @@ static char * make_string(char ** inp)
                noeval = 1;
        for (n = 0; inp[n]; n++) {
                p = insert_var_value_sub(inp[n], noeval);
-               str = xrealloc(str, (len + strlen(p)));
+               str = xrealloc(str, (len + strlen(p) + (2 * nonnull[n])));
                if (n) {
                        strcat(str, " ");
                } else {
                        *str = '\0';
                }
+               if (nonnull[n])
+                       strcat(str, "'");
                strcat(str, p);
+               if (nonnull[n])
+                       strcat(str, "'");
                len = strlen(str) + 3;
                if (p != inp[n]) free(p);
        }