From: Denis Vlasenko Date: Wed, 16 May 2007 09:36:55 +0000 (-0000) Subject: hush: fix incorrect processing of echo "'$var'". X-Git-Tag: 1_6_0~63 X-Git-Url: https://git.librecmc.org/?a=commitdiff_plain;h=8f6bdb42df745425ba0ac085467105e9cc61c817;p=oweals%2Fbusybox.git hush: fix incorrect processing of echo "'$var'". hush: rename map[] and MAP_xxx, making them easier to understand. hush: move testcase (which now passes) from hush-bugs to hush-parsing --- diff --git a/shell/hush.c b/shell/hush.c index 87e003db4..e49c0c989 100644 --- a/shell/hush.c +++ b/shell/hush.c @@ -71,7 +71,7 @@ * memory leak finding and plugging - done? * more testing, especially quoting rules and redirection * document how quoting rules not precisely followed for variable assignments - * maybe change map[] to use 2-bit entries + * maybe change charmap[] to use 2-bit entries * (eventually) remove all the printf's * * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. @@ -281,12 +281,12 @@ extern char **environ; /* This is in , but protected with __USE_GNU */ /* "globals" within this file */ enum { - MAP_ORDINARY = 0, - MAP_FLOWTROUGH_IF_QUOTED = 1, - MAP_IFS_IF_UNQUOTED = 2, /* flow through if quoted too */ - MAP_NEVER_FLOWTROUGH = 3, + CHAR_ORDINARY = 0, + CHAR_ORDINARY_IF_QUOTED = 1, /* example: *, # */ + CHAR_IFS = 2, /* treated as ordinary if quoted */ + CHAR_SPECIAL = 3, /* example: $ */ }; -static unsigned char map[256]; +static unsigned char charmap[256]; static const char *ifs; static int fake_mode; static struct close_me *close_me_head; @@ -2311,7 +2311,7 @@ static int xglob(o_string *dest, int flags, glob_t *pglob) * Caller can deallocate entire list by single free(list). */ /* Helpers first: - * count_XXX estimates, how large block do we need. It's okay + * count_XXX estimates size of the block we need. It's okay * to over-estimate sizes a bit, if it makes code simpler */ static int count_ifs(const char *str) { @@ -3360,17 +3360,17 @@ static int parse_stream(o_string *dest, struct p_context *ctx, debug_printf_parse("parse_stream entered, end_trigger='%s'\n", end_trigger); while ((ch = b_getch(input)) != EOF) { - m = map[ch]; + m = charmap[ch]; next = (ch == '\n') ? '\0' : b_peek(input); debug_printf_parse(": ch=%c (%d) m=%d quote=%d\n", ch, ch, m, dest->quote); - if (m == MAP_ORDINARY - || (m != MAP_NEVER_FLOWTROUGH && dest->quote) + if (m == CHAR_ORDINARY + || (m != CHAR_SPECIAL && dest->quote) ) { b_addqchr(dest, ch, dest->quote); continue; } - if (m == MAP_IFS_IF_UNQUOTED) { + if (m == CHAR_IFS) { if (done_word(dest, ctx)) { debug_printf_parse("parse_stream return 1: done_word!=0\n"); return 1; @@ -3388,7 +3388,7 @@ static int parse_stream(o_string *dest, struct p_context *ctx, debug_printf_parse("parse_stream return 0: end_trigger char found\n"); return 0; } - if (m == MAP_IFS_IF_UNQUOTED) + if (m == CHAR_IFS) continue; switch (ch) { case '#': @@ -3527,28 +3527,28 @@ static int parse_stream(o_string *dest, struct p_context *ctx, return 0; } -static void mapset(const char *set, int code) +static void set_in_charmap(const char *set, int code) { while (*set) - map[(unsigned char)*set++] = code; + charmap[(unsigned char)*set++] = code; } -static void update_ifs_map(void) +static void update_charmap(void) { - /* char *ifs and char map[256] are both globals. */ + /* char *ifs and char charmap[256] are both globals. */ ifs = getenv("IFS"); if (ifs == NULL) ifs = " \t\n"; /* Precompute a list of 'flow through' behavior so it can be treated * quickly up front. Computation is necessary because of IFS. * Special case handling of IFS == " \t\n" is not implemented. - * The map[] array only really needs two bits each, and on most machines - * that would be faster because of the reduced L1 cache footprint. + * The charmap[] array only really needs two bits each, + * and on most machines that would be faster (reduced L1 cache use). */ - memset(map, MAP_ORDINARY, sizeof(map)); /* most chars flow through always */ - mapset("\\$'\"`", MAP_NEVER_FLOWTROUGH); - mapset("<>;&|(){}#", MAP_FLOWTROUGH_IF_QUOTED); - mapset(ifs, MAP_IFS_IF_UNQUOTED); /* also flow through if quoted */ + memset(charmap, CHAR_ORDINARY, sizeof(charmap)); + set_in_charmap("\\$\"`", CHAR_SPECIAL); + set_in_charmap("<>;&|(){}#'", CHAR_ORDINARY_IF_QUOTED); + set_in_charmap(ifs, CHAR_IFS); /* also flow through if quoted */ } /* most recursion does not come through here, the exception is @@ -3561,9 +3561,9 @@ static int parse_stream_outer(struct in_str *inp, int parse_flag) do { ctx.parse_type = parse_flag; initialize_context(&ctx); - update_ifs_map(); + update_charmap(); if (!(parse_flag & FLAG_PARSE_SEMICOLON) || (parse_flag & FLAG_REPARSING)) - mapset(";$&|", MAP_ORDINARY); + set_in_charmap(";$&|", CHAR_ORDINARY); #if ENABLE_HUSH_INTERACTIVE inp->promptmode = 1; #endif @@ -3665,7 +3665,7 @@ int hush_main(int argc, char **argv) * hush_main(), therefore we cannot rely on the BSS to zero out this * stuff. Reset these to 0 every time. */ ifs = NULL; - /* map[] is taken care of with call to update_ifs_map() */ + /* charmap[] is taken care of with call to update_charmap() */ fake_mode = 0; close_me_head = NULL; #if ENABLE_HUSH_INTERACTIVE diff --git a/shell/hush_test/hush-bugs/quote1.right b/shell/hush_test/hush-bugs/quote1.right deleted file mode 100644 index cb382054c..000000000 --- a/shell/hush_test/hush-bugs/quote1.right +++ /dev/null @@ -1 +0,0 @@ -'1' diff --git a/shell/hush_test/hush-bugs/quote1.tests b/shell/hush_test/hush-bugs/quote1.tests deleted file mode 100755 index f55895466..000000000 --- a/shell/hush_test/hush-bugs/quote1.tests +++ /dev/null @@ -1,2 +0,0 @@ -a=1 -echo "'$a'" diff --git a/shell/hush_test/hush-parsing/quote1.right b/shell/hush_test/hush-parsing/quote1.right new file mode 100644 index 000000000..cb382054c --- /dev/null +++ b/shell/hush_test/hush-parsing/quote1.right @@ -0,0 +1 @@ +'1' diff --git a/shell/hush_test/hush-parsing/quote1.tests b/shell/hush_test/hush-parsing/quote1.tests new file mode 100755 index 000000000..f55895466 --- /dev/null +++ b/shell/hush_test/hush-parsing/quote1.tests @@ -0,0 +1,2 @@ +a=1 +echo "'$a'"