diff --git a/ChangeLog b/ChangeLog index ba6c2f542..40f58a42e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2012-06-08 Vladimir Serbinenko + + Fix wildcard escaping. + + * grub-core/commands/wildcard.c (wildcard_escape): Moved from here ... + * grub-core/script/execute.c (wildcard_escape): .. to here. + Don't escape dot. + * grub-core/commands/wildcard.c (wildcard_unescape): Moved from here ... + * grub-core/script/execute.c (wildcard_unescape): .. to here. + Don't escape dot. + * grub-core/script/execute.c (gettext_append): Always escape. + (grub_script_arglist_to_argv): Always handle escaping/unescaping. + * grub-core/script/yylex.l: Don't cut away the escaping. + * tests/grub_script_echo1.in: Add tests with wildcard. + 2012-06-08 Vladimir Serbinenko * grub-core/bus/usb/serial/ftdi.c (real_config): Handle 1.5 stop bits. diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c index c98eed4da..2883b2096 100644 --- a/grub-core/commands/wildcard.c +++ b/grub-core/commands/wildcard.c @@ -36,14 +36,10 @@ static char ** match_devices (const regex_t *regexp, int noparts); static char ** match_files (const char *prefix, const char *suffix_start, const char *suffix_end, const regex_t *regexp); -static char* wildcard_escape (const char *s); -static char* wildcard_unescape (const char *s); static grub_err_t wildcard_expand (const char *s, char ***strs); struct grub_script_wildcard_translator grub_filename_translator = { .expand = wildcard_expand, - .escape = wildcard_escape, - .unescape = wildcard_unescape }; static char ** @@ -414,55 +410,6 @@ check_file (const char *dir, const char *basename) return found; } -static char* -wildcard_escape (const char *s) -{ - int i; - int len; - char ch; - char *p; - - len = grub_strlen (s); - p = grub_malloc (len * 2 + 1); - if (! p) - return NULL; - - i = 0; - while ((ch = *s++)) - { - if (isregexop (ch)) - p[i++] = '\\'; - p[i++] = ch; - } - p[i] = '\0'; - return p; -} - -static char* -wildcard_unescape (const char *s) -{ - int i; - int len; - char ch; - char *p; - - len = grub_strlen (s); - p = grub_malloc (len + 1); - if (! p) - return NULL; - - i = 0; - while ((ch = *s++)) - { - if (ch == '\\' && isregexop (*s)) - p[i++] = *s++; - else - p[i++] = ch; - } - p[i] = '\0'; - return p; -} - static grub_err_t wildcard_expand (const char *s, char ***strs) { diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c index 38481c0f4..0331a9501 100644 --- a/grub-core/script/execute.c +++ b/grub-core/script/execute.c @@ -52,6 +52,55 @@ static struct grub_script_scope *scope = 0; /* Wildcard translator for GRUB script. */ struct grub_script_wildcard_translator *grub_wildcard_translator; +static char* +wildcard_escape (const char *s) +{ + int i; + int len; + char ch; + char *p; + + len = grub_strlen (s); + p = grub_malloc (len * 2 + 1); + if (! p) + return NULL; + + i = 0; + while ((ch = *s++)) + { + if (ch == '*' || ch == '\\') + p[i++] = '\\'; + p[i++] = ch; + } + p[i] = '\0'; + return p; +} + +static char* +wildcard_unescape (const char *s) +{ + int i; + int len; + char ch; + char *p; + + len = grub_strlen (s); + p = grub_malloc (len + 1); + if (! p) + return NULL; + + i = 0; + while ((ch = *s++)) + { + if (ch == '\\') + p[i++] = *s++; + else + p[i++] = ch; + } + p[i] = '\0'; + return p; +} + static void replace_scope (struct grub_script_scope *new_scope) { @@ -504,20 +553,14 @@ gettext_append (struct grub_script_argv *result, const char *orig_str) goto fail; *ptr = 0; - if (grub_wildcard_translator) + char *escaped = 0; + escaped = wildcard_escape (res); + if (grub_script_argv_append (result, escaped, grub_strlen (escaped))) { - char *escaped = 0; - escaped = grub_wildcard_translator->escape (res); - if (grub_script_argv_append (result, escaped, grub_strlen (escaped))) - { - grub_free (escaped); - goto fail; - } grub_free (escaped); - } - else - if (grub_script_argv_append (result, res, ptr - res)) goto fail; + } + grub_free (escaped); rval = 0; fail: @@ -547,13 +590,13 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, int r; char *p = 0; - if (! grub_wildcard_translator || escape_type == 0) + if (escape_type == 0) return grub_script_argv_append (&result, s, grub_strlen (s)); if (escape_type > 0) - p = grub_wildcard_translator->escape (s); + p = wildcard_escape (s); else if (escape_type < 0) - p = grub_wildcard_translator->unescape (s); + p = wildcard_unescape (s); if (! p) return 1; @@ -636,48 +679,46 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist, /* Perform wildcard expansion. */ - if (grub_wildcard_translator) - { - int j; - int failed = 0; - char **expansions = 0; - struct grub_script_argv unexpanded = result; + int j; + int failed = 0; + struct grub_script_argv unexpanded = result; - result.argc = 0; - result.args = 0; - for (i = 0; unexpanded.args[i]; i++) + result.argc = 0; + result.args = 0; + for (i = 0; unexpanded.args[i]; i++) + { + char **expansions = 0; + if (grub_wildcard_translator + && grub_wildcard_translator->expand (unexpanded.args[i], + &expansions)) { - if (grub_wildcard_translator->expand (unexpanded.args[i], - &expansions)) + grub_script_argv_free (&unexpanded); + goto fail; + } + + if (! expansions) + { + grub_script_argv_next (&result); + append (unexpanded.args[i], -1); + } + else + { + for (j = 0; expansions[j]; j++) + { + failed = (failed || grub_script_argv_next (&result) || + append (expansions[j], -1)); + grub_free (expansions[j]); + } + grub_free (expansions); + + if (failed) { grub_script_argv_free (&unexpanded); goto fail; } - - if (! expansions) - { - grub_script_argv_next (&result); - append (unexpanded.args[i], -1); - } - else - { - for (j = 0; expansions[j]; j++) - { - failed = (failed || grub_script_argv_next (&result) || - append (expansions[j], -1)); - grub_free (expansions[j]); - } - grub_free (expansions); - - if (failed) - { - grub_script_argv_free (&unexpanded); - goto fail; - } - } } - grub_script_argv_free (&unexpanded); } + grub_script_argv_free (&unexpanded); *argv = result; return 0; diff --git a/grub-core/script/yylex.l b/grub-core/script/yylex.l index a8e66cfd4..f6a39c54b 100644 --- a/grub-core/script/yylex.l +++ b/grub-core/script/yylex.l @@ -230,7 +230,7 @@ POS_MULTILINE {WORD}?\\\n /* Split word into multiple args */ { - \\. { COPY (yytext + 1, yyleng - 1); } + \\. { COPY (yytext, yyleng); } \\\n { /* ignore */ } \" { yy_push_state (DQUOTE, yyscanner); diff --git a/include/grub/script_sh.h b/include/grub/script_sh.h index b4c3f40ef..d99cbf74c 100644 --- a/include/grub/script_sh.h +++ b/include/grub/script_sh.h @@ -85,8 +85,6 @@ struct grub_script_argv /* Pluggable wildcard translator. */ struct grub_script_wildcard_translator { - char *(*escape) (const char *str); - char *(*unescape) (const char *str); grub_err_t (*expand) (const char *str, char ***expansions); }; extern struct grub_script_wildcard_translator *grub_wildcard_translator; diff --git a/tests/grub_script_echo1.in b/tests/grub_script_echo1.in index 620911795..3a07972a9 100644 --- a/tests/grub_script_echo1.in +++ b/tests/grub_script_echo1.in @@ -174,3 +174,10 @@ $var if test x$grubshell = xyes; then insmod regexp; fi echo /boot/grub/i386-pc/normal.mod +echo x\\y +echo x\*y +echo x\\ +echo x\\\\ +echo x\\\\y + +