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>
This commit is contained in:
parent
641b0d374e
commit
a005f19eff
@ -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
|
||||
@ -3467,6 +3488,11 @@ final_return:
|
||||
#endif
|
||||
|
||||
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;
|
||||
@ -3474,19 +3500,46 @@ static char *insert_var_value(char *inp)
|
||||
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, " ");
|
||||
|
Loading…
Reference in New Issue
Block a user