+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.
static inline int
isregexop (char ch)
{
- return grub_strchr ("*.\\", ch) ? 1 : 0;
+ return grub_strchr ("*.\\|+{}[]?", ch) ? 1 : 0;
}
static char *
buffer[i++] = '^';
while (start < end)
{
- /* XXX Only * expansion for now. */
+ /* XXX Only * and ? expansion for now. */
switch ((ch = *start++))
{
case '\\':
case '(':
case ')':
case '@':
+ case '+':
+ case '|':
+ case '{':
+ case '}':
+ case '[':
+ case ']':
buffer[i++] = '\\';
buffer[i++] = ch;
break;
buffer[i++] = '*';
break;
+ case '?':
+ buffer[i++] = '.';
+ break;
+
default:
buffer[i++] = ch;
}
if (ch == '\\' && end[1])
end++;
- else if (isregexop (ch))
+ else if (ch == '*' || ch == '?')
regex = 1;
else if (ch == '/' && ! regex)
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)
{
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
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
i = 0;
while ((ch = *s++))
{
- if (ch == '*' || ch == '\\')
+ if (ch == '*' || ch == '\\' || ch == '?')
p[i++] = '\\';
p[i++] = ch;
}
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);