]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
Fix wildcard regexp dot and other special characters handling.
authorVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 19 Jun 2012 12:13:19 +0000 (14:13 +0200)
committerVladimir 'phcoder' Serbinenko <phcoder@gmail.com>
Tue, 19 Jun 2012 12:13:19 +0000 (14:13 +0200)
Reported by: Robert Mabee.

* grub-core/commands/wildcard.c (isregexop): Add "|+{}[]?".
(make_regex): Escape "|+{}[]". Transform '?' to '.?'.
(split_path): Trigger expansion on '?'.
(unescape): New function.
(wildcard_expand): Unescape parts copied without globbing.
* grub-core/script/execute.c (wildcard_escape): Escape '?'.
(grub_script_arglist_to_argv): Don't unescape expansions.

ChangeLog
grub-core/commands/wildcard.c
grub-core/script/execute.c

index 13ef6b06bc8629794a39e6611346377f670fbce3..c57658564757e4a4d2d9fedeea57cd450684bc9c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2012-06-19  Vladimir Serbinenko  <phcoder@gmail.com>
+
+       Fix wildcard regexp dot and other special characters handling.
+       Reported by: Robert Mabee.
+
+       * grub-core/commands/wildcard.c (isregexop): Add "|+{}[]?".
+       (make_regex): Escape "|+{}[]". Transform '?' to '.?'.
+       (split_path): Trigger expansion on '?'.
+       (unescape): New function.
+       (wildcard_expand): Unescape parts copied without globbing.
+       * grub-core/script/execute.c (wildcard_escape): Escape '?'.
+       (grub_script_arglist_to_argv): Don't unescape expansions.
+
 2012-06-19  Vladimir Serbinenko  <phcoder@gmail.com>
 
        * include/grub/net.h (grub_net_card): New member txbufsize.
index 2883b2096fb05ab9cbf3e2e7304353da8d17024b..56eea10b782591267c8f82ddd8086d50cc25cb94 100644 (file)
@@ -80,7 +80,7 @@ merge (char **dest, char **ps)
 static inline int
 isregexop (char ch)
 {
-  return grub_strchr ("*.\\", ch) ? 1 : 0;
+  return grub_strchr ("*.\\|+{}[]?", ch) ? 1 : 0;
 }
 
 static char *
@@ -123,7 +123,7 @@ make_regex (const char *start, const char *end, regex_t *regexp)
   buffer[i++] = '^';
   while (start < end)
     {
-      /* XXX Only * expansion for now.  */
+      /* XXX Only * and ? expansion for now.  */
       switch ((ch = *start++))
        {
        case '\\':
@@ -136,6 +136,12 @@ make_regex (const char *start, const char *end, regex_t *regexp)
        case '(':
        case ')':
        case '@':
+       case '+':
+       case '|':
+       case '{':
+       case '}':
+       case '[':
+       case ']':
          buffer[i++] = '\\';
          buffer[i++] = ch;
          break;
@@ -145,6 +151,10 @@ make_regex (const char *start, const char *end, regex_t *regexp)
          buffer[i++] = '*';
          break;
 
+       case '?':
+         buffer[i++] = '.';
+         break;
+
        default:
          buffer[i++] = ch;
        }
@@ -181,7 +191,7 @@ split_path (const char *str, const char **noregexop, const char **regexop)
       if (ch == '\\' && end[1])
        end++;
 
-      else if (isregexop (ch))
+      else if (ch == '*' || ch == '?')
        regex = 1;
 
       else if (ch == '/' && ! regex)
@@ -410,6 +420,27 @@ check_file (const char *dir, const char *basename)
   return found;
 }
 
+static void
+unescape (char *out, const char *in, const char *end)
+{
+  char *optr;
+  const char *iptr;
+
+  for (optr = out, iptr = in; iptr < end;)
+    {
+      if (*iptr == '\\' && iptr + 1 < end)
+       {
+         *optr++ = iptr[1];
+         iptr += 2;
+         continue;
+       }
+      if (*iptr == '\\')
+       break;
+      *optr++ = *iptr++;
+    }
+  *optr = 0;
+}
+
 static grub_err_t
 wildcard_expand (const char *s, char ***strs)
 {
@@ -442,8 +473,7 @@ wildcard_expand (const char *s, char ***strs)
              paths[0] = grub_malloc (regexop - start + 1);
              if (!paths[0])
                goto fail;
-             grub_memcpy (paths[0], start, regexop - start);
-             paths[0][regexop - start] = '\0';
+             unescape (paths[0], start, regexop);
              paths[1] = 0;
            }
          else
@@ -460,8 +490,8 @@ wildcard_expand (const char *s, char ***strs)
                  if (!n)
                    goto fail;
                  grub_memcpy (n, o, oend - o);
-                 grub_memcpy (n + (oend - o), start, regexop - start);
-                 n[(oend - o) + (regexop - start)] = '\0';
+
+                 unescape (n + (oend - o), start, regexop);
                  if (had_regexp)
                    p = grub_strrchr (n, '/');
                  else
index 0331a9501ddecb70ee84658f350ef239f1a08d3b..8855bc126ea7e80d43563b60d0d89e4415daa5be 100644 (file)
@@ -68,7 +68,7 @@ wildcard_escape (const char *s)
   i = 0;
   while ((ch = *s++))
     {
-      if (ch == '*' || ch == '\\')
+      if (ch == '*' || ch == '\\' || ch == '?')
        p[i++] = '\\';
       p[i++] = ch;
     }
@@ -706,7 +706,7 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
          for (j = 0; expansions[j]; j++)
            {
              failed = (failed || grub_script_argv_next (&result) ||
-                       append (expansions[j], -1));
+                       append (expansions[j], 0));
              grub_free (expansions[j]);
            }
          grub_free (expansions);