hush: fix "export not_yet_defined_var", fix parsing of "cmd | }"
corner case; improve hush_leaktool.sh; fix some false positives in testsuite function old new delta builtin_export 191 206 +15 parse_stream 2196 2200 +4
This commit is contained in:
parent
3798db58cf
commit
dcd78c4d0f
45
shell/hush.c
45
shell/hush.c
@ -4459,10 +4459,6 @@ static int done_word(o_string *word, struct parse_context *ctx)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
command->argv = add_string_to_strings(command->argv, xstrdup(word->data));
|
command->argv = add_string_to_strings(command->argv, xstrdup(word->data));
|
||||||
//SEGV, but good idea.
|
|
||||||
// command->argv = add_string_to_strings(command->argv, word->data);
|
|
||||||
// word->data = NULL;
|
|
||||||
// word->length = 0;
|
|
||||||
debug_print_strings("word appended to argv", command->argv);
|
debug_print_strings("word appended to argv", command->argv);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -5481,14 +5477,16 @@ static struct pipe *parse_stream(char **pstring,
|
|||||||
* } is an ordinary char in this case, even inside { cmd; }
|
* } is an ordinary char in this case, even inside { cmd; }
|
||||||
* Pathological example: { ""}; } should exec "}" cmd
|
* Pathological example: { ""}; } should exec "}" cmd
|
||||||
*/
|
*/
|
||||||
if (ch == '}'
|
if (ch == '}') {
|
||||||
&& !(IS_NULL_PIPE(ctx.pipe)
|
if (!IS_NULL_CMD(ctx.command) /* cmd } */
|
||||||
&& IS_NULL_CMD(ctx.command)
|
|| dest.length != 0 /* word} */
|
||||||
&& dest.length == 0
|
|| dest.o_quoted /* ""} */
|
||||||
&& !dest.o_quoted
|
) {
|
||||||
)
|
goto ordinary_char;
|
||||||
) {
|
}
|
||||||
goto ordinary_char;
|
if (!IS_NULL_PIPE(ctx.pipe)) /* cmd | } */
|
||||||
|
goto skip_end_trigger;
|
||||||
|
/* else: } does terminate a group */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end_trigger && end_trigger == ch
|
if (end_trigger && end_trigger == ch
|
||||||
@ -5531,6 +5529,7 @@ static struct pipe *parse_stream(char **pstring,
|
|||||||
return ctx.list_head;
|
return ctx.list_head;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
skip_end_trigger:
|
||||||
if (is_ifs)
|
if (is_ifs)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -6420,12 +6419,11 @@ static int builtin_export(char **argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
const char *value;
|
|
||||||
char *name = *argv;
|
char *name = *argv;
|
||||||
|
|
||||||
value = strchr(name, '=');
|
/* So far we do not check that name is valid */
|
||||||
if (!value) {
|
if (strchr(name, '=') == NULL) {
|
||||||
/* They are exporting something without a =VALUE */
|
/* Exporting a name without a =VALUE */
|
||||||
struct variable *var;
|
struct variable *var;
|
||||||
|
|
||||||
var = get_local_var(name);
|
var = get_local_var(name);
|
||||||
@ -6433,12 +6431,19 @@ static int builtin_export(char **argv)
|
|||||||
var->flg_export = 1;
|
var->flg_export = 1;
|
||||||
debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
|
debug_printf_env("%s: putenv '%s'\n", __func__, var->varstr);
|
||||||
putenv(var->varstr);
|
putenv(var->varstr);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
/* bash does not return an error when trying to export
|
/* Exporting non-existing variable.
|
||||||
* an undefined variable. Do likewise. */
|
* bash does not put it in environment,
|
||||||
continue;
|
* but remembers that it is exported,
|
||||||
|
* and does put it in env when it is set later.
|
||||||
|
* We just set it to "" and export. */
|
||||||
|
name = xasprintf("%s=", name);
|
||||||
|
} else {
|
||||||
|
/* Exporting VAR=VALUE */
|
||||||
|
name = xstrdup(name);
|
||||||
}
|
}
|
||||||
set_local_var(xstrdup(name), 1, 0);
|
set_local_var(name, 1, 0);
|
||||||
} while (*++argv);
|
} while (*++argv);
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
|
@ -6,8 +6,20 @@ output=output
|
|||||||
freelist=`grep 'free 0x' "$output" | cut -d' ' -f2 | sort | uniq | xargs`
|
freelist=`grep 'free 0x' "$output" | cut -d' ' -f2 | sort | uniq | xargs`
|
||||||
|
|
||||||
grep -v free "$output" >"$output.leaked"
|
grep -v free "$output" >"$output.leaked"
|
||||||
|
|
||||||
|
i=8
|
||||||
|
list=
|
||||||
for freed in $freelist; do
|
for freed in $freelist; do
|
||||||
echo Dropping $freed
|
list="$list -e $freed"
|
||||||
grep -v $freed <"$output.leaked" >"$output.temp"
|
test $((--i)) != 0 && continue
|
||||||
|
echo Dropping $list
|
||||||
|
grep -F -v $list <"$output.leaked" >"$output.temp"
|
||||||
mv "$output.temp" "$output.leaked"
|
mv "$output.temp" "$output.leaked"
|
||||||
|
i=8
|
||||||
|
list=
|
||||||
done
|
done
|
||||||
|
if test "$list"; then
|
||||||
|
echo Dropping $list
|
||||||
|
grep -F -v $list <"$output.leaked" >"$output.temp"
|
||||||
|
mv "$output.temp" "$output.leaked"
|
||||||
|
fi
|
||||||
|
@ -2,3 +2,4 @@ sending USR2
|
|||||||
caught
|
caught
|
||||||
sending USR2
|
sending USR2
|
||||||
sending USR2
|
sending USR2
|
||||||
|
USR2
|
||||||
|
@ -67,6 +67,7 @@ HERE
|
|||||||
f >/dev/null
|
f >/dev/null
|
||||||
: $((i++))
|
: $((i++))
|
||||||
done
|
done
|
||||||
|
unset -f f
|
||||||
|
|
||||||
memleak
|
memleak
|
||||||
|
|
||||||
@ -133,6 +134,7 @@ HERE
|
|||||||
f >/dev/null
|
f >/dev/null
|
||||||
: $((i++))
|
: $((i++))
|
||||||
done
|
done
|
||||||
|
unset -f f
|
||||||
|
|
||||||
|
|
||||||
memleak
|
memleak
|
||||||
|
Loading…
Reference in New Issue
Block a user