summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Hershberger <joe.hershberger@ni.com>2012-08-17 10:26:30 +0000
committerWolfgang Denk <wd@denx.de>2012-09-02 20:31:21 +0200
commita005f19eff946454985785788c344f10616d571e (patch)
tree0399c46a5551a7a83c37f75574891126019ef378
parent641b0d374eeea65778bf8cb2107064c2aff195eb (diff)
downloadu-boot-imx-a005f19eff946454985785788c344f10616d571e.zip
u-boot-imx-a005f19eff946454985785788c344f10616d571e.tar.gz
u-boot-imx-a005f19eff946454985785788c344f10616d571e.tar.bz2
hush: Don't parse the contents of a dereferenced var
When a variable which contains a user-supplied value is dereferenced (e.g. to be echo'ed), make sure that the value is not further parsed by hush. Set the hush local variable "HUSH_NO_EVAL=1" to enable this behavior. Without this patch, a sequence like this occurs: Panda # env set my_user_string Bob\'s favorite device Panda # print my_user_string my_user_string=Bob's favorite device Panda # echo $my_user_string syntax error hush.c:3007 With this patch, it looks like this: Panda # HUSH_NO_EVAL=1 Panda # env set my_user_string Bob\'s favorite device Panda # print my_user_string my_user_string=Bob's favorite device Panda # echo $my_user_string Bob's favorite device Signed-off-by: Joe Hershberger <joe.hershberger@ni.com>
-rw-r--r--common/hush.c64
1 files changed, 61 insertions, 3 deletions
diff --git a/common/hush.c b/common/hush.c
index 39cf203..4c84c2f 100644
--- a/common/hush.c
+++ b/common/hush.c
@@ -127,6 +127,7 @@
#endif
#endif
#define SPECIAL_VAR_SYMBOL 03
+#define SUBSTED_VAR_SYMBOL 04
#ifndef __U_BOOT__
#define FLAG_EXIT_FROM_LOOP 1
#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */
@@ -499,6 +500,7 @@ static void remove_bg_job(struct pipe *pi);
/* local variable support */
static char **make_list_in(char **inp, char *name);
static char *insert_var_value(char *inp);
+static char *insert_var_value_sub(char *inp, int tag_subst);
#ifndef __U_BOOT__
/* Table of built-in functions. They can be forked or not, depending on
@@ -3088,6 +3090,21 @@ int parse_stream(o_string *dest, struct p_context *ctx,
return 1;
break;
#endif
+ case SUBSTED_VAR_SYMBOL:
+ dest->nonnull = 1;
+ while (ch = b_getch(input), ch != EOF &&
+ ch != SUBSTED_VAR_SYMBOL) {
+ debug_printf("subst, pass=%d\n", ch);
+ if (input->__promptme == 0)
+ return 1;
+ b_addchr(dest, ch);
+ }
+ debug_printf("subst, term=%d\n", ch);
+ if (ch == EOF) {
+ syntax();
+ return 1;
+ }
+ break;
default:
syntax(); /* this is really an internal logic error */
return 1;
@@ -3129,6 +3146,10 @@ void update_ifs_map(void)
mapset((uchar *)"\\$'\"`", 3); /* never flow through */
mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */
#else
+ {
+ uchar subst[2] = {SUBSTED_VAR_SYMBOL, 0};
+ mapset(subst, 3); /* never flow through */
+ }
mapset((uchar *)"\\$'\"", 3); /* never flow through */
mapset((uchar *)";&|#", 1); /* flow through if quoted */
#endif
@@ -3468,25 +3489,57 @@ final_return:
static char *insert_var_value(char *inp)
{
+ return insert_var_value_sub(inp, 0);
+}
+
+static char *insert_var_value_sub(char *inp, int tag_subst)
+{
int res_str_len = 0;
int len;
int done = 0;
char *p, *p1, *res_str = NULL;
while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
+ /* check the beginning of the string for normal charachters */
if (p != inp) {
+ /* copy any charachters to the result string */
len = p - inp;
res_str = xrealloc(res_str, (res_str_len + len));
strncpy((res_str + res_str_len), inp, len);
res_str_len += len;
}
inp = ++p;
+ /* find the ending marker */
p = strchr(inp, SPECIAL_VAR_SYMBOL);
*p = '\0';
+ /* look up the value to substitute */
if ((p1 = lookup_param(inp))) {
- len = res_str_len + strlen(p1);
+ if (tag_subst)
+ len = res_str_len + strlen(p1) + 2;
+ else
+ len = res_str_len + strlen(p1);
res_str = xrealloc(res_str, (1 + len));
- strcpy((res_str + res_str_len), p1);
+ if (tag_subst) {
+ /*
+ * copy the variable value to the result
+ * string
+ */
+ strcpy((res_str + res_str_len + 1), p1);
+
+ /*
+ * mark the replaced text to be accepted as
+ * is
+ */
+ res_str[res_str_len] = SUBSTED_VAR_SYMBOL;
+ res_str[res_str_len + 1 + strlen(p1)] =
+ SUBSTED_VAR_SYMBOL;
+ } else
+ /*
+ * copy the variable value to the result
+ * string
+ */
+ strcpy((res_str + res_str_len), p1);
+
res_str_len = len;
}
*p = SPECIAL_VAR_SYMBOL;
@@ -3550,9 +3603,14 @@ static char * make_string(char ** inp)
char *str = NULL;
int n;
int len = 2;
+ char *noeval_str;
+ int noeval = 0;
+ noeval_str = get_local_var("HUSH_NO_EVAL");
+ if (noeval_str != NULL && *noeval_str != '0' && *noeval_str != '\0')
+ noeval = 1;
for (n = 0; inp[n]; n++) {
- p = insert_var_value(inp[n]);
+ p = insert_var_value_sub(inp[n], noeval);
str = xrealloc(str, (len + strlen(p)));
if (n) {
strcat(str, " ");