mirror of
https://github.com/Fishwaldo/u-boot.git
synced 2025-03-21 06:31:31 +00:00
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
1 changed files with 61 additions and 3 deletions
|
@ -127,6 +127,7 @@
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#define SPECIAL_VAR_SYMBOL 03
|
#define SPECIAL_VAR_SYMBOL 03
|
||||||
|
#define SUBSTED_VAR_SYMBOL 04
|
||||||
#ifndef __U_BOOT__
|
#ifndef __U_BOOT__
|
||||||
#define FLAG_EXIT_FROM_LOOP 1
|
#define FLAG_EXIT_FROM_LOOP 1
|
||||||
#define FLAG_PARSE_SEMICOLON (1 << 1) /* symbol ';' is special for parser */
|
#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 */
|
/* local variable support */
|
||||||
static char **make_list_in(char **inp, char *name);
|
static char **make_list_in(char **inp, char *name);
|
||||||
static char *insert_var_value(char *inp);
|
static char *insert_var_value(char *inp);
|
||||||
|
static char *insert_var_value_sub(char *inp, int tag_subst);
|
||||||
|
|
||||||
#ifndef __U_BOOT__
|
#ifndef __U_BOOT__
|
||||||
/* Table of built-in functions. They can be forked or not, depending on
|
/* 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;
|
return 1;
|
||||||
break;
|
break;
|
||||||
#endif
|
#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:
|
default:
|
||||||
syntax(); /* this is really an internal logic error */
|
syntax(); /* this is really an internal logic error */
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -3129,6 +3146,10 @@ void update_ifs_map(void)
|
||||||
mapset((uchar *)"\\$'\"`", 3); /* never flow through */
|
mapset((uchar *)"\\$'\"`", 3); /* never flow through */
|
||||||
mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */
|
mapset((uchar *)"<>;&|(){}#", 1); /* flow through if quoted */
|
||||||
#else
|
#else
|
||||||
|
{
|
||||||
|
uchar subst[2] = {SUBSTED_VAR_SYMBOL, 0};
|
||||||
|
mapset(subst, 3); /* never flow through */
|
||||||
|
}
|
||||||
mapset((uchar *)"\\$'\"", 3); /* never flow through */
|
mapset((uchar *)"\\$'\"", 3); /* never flow through */
|
||||||
mapset((uchar *)";&|#", 1); /* flow through if quoted */
|
mapset((uchar *)";&|#", 1); /* flow through if quoted */
|
||||||
#endif
|
#endif
|
||||||
|
@ -3467,6 +3488,11 @@ final_return:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char *insert_var_value(char *inp)
|
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 res_str_len = 0;
|
||||||
int len;
|
int len;
|
||||||
|
@ -3474,19 +3500,46 @@ static char *insert_var_value(char *inp)
|
||||||
char *p, *p1, *res_str = NULL;
|
char *p, *p1, *res_str = NULL;
|
||||||
|
|
||||||
while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
|
while ((p = strchr(inp, SPECIAL_VAR_SYMBOL))) {
|
||||||
|
/* check the beginning of the string for normal charachters */
|
||||||
if (p != inp) {
|
if (p != inp) {
|
||||||
|
/* copy any charachters to the result string */
|
||||||
len = p - inp;
|
len = p - inp;
|
||||||
res_str = xrealloc(res_str, (res_str_len + len));
|
res_str = xrealloc(res_str, (res_str_len + len));
|
||||||
strncpy((res_str + res_str_len), inp, len);
|
strncpy((res_str + res_str_len), inp, len);
|
||||||
res_str_len += len;
|
res_str_len += len;
|
||||||
}
|
}
|
||||||
inp = ++p;
|
inp = ++p;
|
||||||
|
/* find the ending marker */
|
||||||
p = strchr(inp, SPECIAL_VAR_SYMBOL);
|
p = strchr(inp, SPECIAL_VAR_SYMBOL);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
/* look up the value to substitute */
|
||||||
if ((p1 = lookup_param(inp))) {
|
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));
|
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;
|
res_str_len = len;
|
||||||
}
|
}
|
||||||
*p = SPECIAL_VAR_SYMBOL;
|
*p = SPECIAL_VAR_SYMBOL;
|
||||||
|
@ -3550,9 +3603,14 @@ static char * make_string(char ** inp)
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
int n;
|
int n;
|
||||||
int len = 2;
|
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++) {
|
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)));
|
str = xrealloc(str, (len + strlen(p)));
|
||||||
if (n) {
|
if (n) {
|
||||||
strcat(str, " ");
|
strcat(str, " ");
|
||||||
|
|
Loading…
Add table
Reference in a new issue