|
|
d9d99f |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
d9d99f |
From: Peter Jones <pjones@redhat.com>
|
|
|
d9d99f |
Date: Mon, 1 Oct 2012 13:24:37 -0400
|
|
|
d9d99f |
Subject: [PATCH] Pass "\x[[:hex:]][[:hex:]]" straight through unmolested.
|
|
|
d9d99f |
|
|
|
d9d99f |
---
|
|
|
d9d99f |
grub-core/commands/wildcard.c | 16 +++++++++++++++-
|
|
|
d9d99f |
grub-core/lib/cmdline.c | 34 ++++++++++++++++++++++++++++++++--
|
|
|
d9d99f |
grub-core/script/execute.c | 43 +++++++++++++++++++++++++++++++++++++------
|
|
|
d9d99f |
3 files changed, 84 insertions(+), 9 deletions(-)
|
|
|
d9d99f |
|
|
|
d9d99f |
diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
|
|
|
d9d99f |
index 9b4e72766ff..02c46f9fdfa 100644
|
|
|
d9d99f |
--- a/grub-core/commands/wildcard.c
|
|
|
d9d99f |
+++ b/grub-core/commands/wildcard.c
|
|
|
d9d99f |
@@ -462,6 +462,12 @@ check_file (const char *dir, const char *basename)
|
|
|
d9d99f |
return ctx.found;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
|
|
|
d9d99f |
+static int
|
|
|
d9d99f |
+is_hex(char c)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
static void
|
|
|
d9d99f |
unescape (char *out, const char *in, const char *end)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
@@ -470,7 +476,15 @@ unescape (char *out, const char *in, const char *end)
|
|
|
d9d99f |
|
|
|
d9d99f |
for (optr = out, iptr = in; iptr < end;)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- if (*iptr == '\\' && iptr + 1 < end)
|
|
|
d9d99f |
+ if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3]))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ *optr++ = *iptr++;
|
|
|
d9d99f |
+ *optr++ = *iptr++;
|
|
|
d9d99f |
+ *optr++ = *iptr++;
|
|
|
d9d99f |
+ *optr++ = *iptr++;
|
|
|
d9d99f |
+ continue;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (*iptr == '\\' && iptr + 1 < end)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
*optr++ = iptr[1];
|
|
|
d9d99f |
iptr += 2;
|
|
|
d9d99f |
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
|
|
|
d9d99f |
index d5e10ee8798..0a5b2afb94b 100644
|
|
|
d9d99f |
--- a/grub-core/lib/cmdline.c
|
|
|
d9d99f |
+++ b/grub-core/lib/cmdline.c
|
|
|
d9d99f |
@@ -20,6 +20,12 @@
|
|
|
d9d99f |
#include <grub/lib/cmdline.h>
|
|
|
d9d99f |
#include <grub/misc.h>
|
|
|
d9d99f |
|
|
|
d9d99f |
+static int
|
|
|
d9d99f |
+is_hex(char c)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
static unsigned int check_arg (char *c, int *has_space)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
int space = 0;
|
|
|
d9d99f |
@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space)
|
|
|
d9d99f |
|
|
|
d9d99f |
while (*c)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- if (*c == '\\' || *c == '\'' || *c == '"')
|
|
|
d9d99f |
+ if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3)))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ size += 4;
|
|
|
d9d99f |
+ c += 4;
|
|
|
d9d99f |
+ continue;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (*c == '\\' || *c == '\'' || *c == '"')
|
|
|
d9d99f |
size++;
|
|
|
d9d99f |
else if (*c == ' ')
|
|
|
d9d99f |
space = 1;
|
|
|
d9d99f |
@@ -85,7 +97,25 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
|
|
|
d9d99f |
|
|
|
d9d99f |
while (*c)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- if (*c == '\\' || *c == '\'' || *c == '"')
|
|
|
d9d99f |
+ if (*c == ' ')
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ *buf++ = '\\';
|
|
|
d9d99f |
+ *buf++ = 'x';
|
|
|
d9d99f |
+ *buf++ = '2';
|
|
|
d9d99f |
+ *buf++ = '0';
|
|
|
d9d99f |
+ c++;
|
|
|
d9d99f |
+ continue;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (*c == '\\' && *(c+1) == 'x' &&
|
|
|
d9d99f |
+ is_hex(*(c+2)) && is_hex(*(c+3)))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ *buf++ = *c++;
|
|
|
d9d99f |
+ *buf++ = *c++;
|
|
|
d9d99f |
+ *buf++ = *c++;
|
|
|
d9d99f |
+ *buf++ = *c++;
|
|
|
d9d99f |
+ continue;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (*c == '\\' || *c == '\'' || *c == '"')
|
|
|
d9d99f |
*buf++ = '\\';
|
|
|
d9d99f |
|
|
|
d9d99f |
*buf++ = *c;
|
|
|
d9d99f |
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
|
|
|
d9d99f |
index ab78ca87f90..cf6cd6601d6 100644
|
|
|
d9d99f |
--- a/grub-core/script/execute.c
|
|
|
d9d99f |
+++ b/grub-core/script/execute.c
|
|
|
d9d99f |
@@ -55,6 +55,12 @@ static struct grub_script_scope *scope = 0;
|
|
|
d9d99f |
/* Wildcard translator for GRUB script. */
|
|
|
d9d99f |
struct grub_script_wildcard_translator *grub_wildcard_translator;
|
|
|
d9d99f |
|
|
|
d9d99f |
+static int
|
|
|
d9d99f |
+is_hex(char c)
|
|
|
d9d99f |
+{
|
|
|
d9d99f |
+ return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
|
|
|
d9d99f |
+}
|
|
|
d9d99f |
+
|
|
|
d9d99f |
static char*
|
|
|
d9d99f |
wildcard_escape (const char *s)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
@@ -71,7 +77,15 @@ wildcard_escape (const char *s)
|
|
|
d9d99f |
i = 0;
|
|
|
d9d99f |
while ((ch = *s++))
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- if (ch == '*' || ch == '\\' || ch == '?')
|
|
|
d9d99f |
+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ p[i++] = ch;
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ continue;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (ch == '*' || ch == '\\' || ch == '?')
|
|
|
d9d99f |
p[i++] = '\\';
|
|
|
d9d99f |
p[i++] = ch;
|
|
|
d9d99f |
}
|
|
|
d9d99f |
@@ -95,7 +109,14 @@ wildcard_unescape (const char *s)
|
|
|
d9d99f |
i = 0;
|
|
|
d9d99f |
while ((ch = *s++))
|
|
|
d9d99f |
{
|
|
|
d9d99f |
- if (ch == '\\')
|
|
|
d9d99f |
+ if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ p[i++] = '\\';
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ p[i++] = *s++;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else if (ch == '\\')
|
|
|
d9d99f |
p[i++] = *s++;
|
|
|
d9d99f |
else
|
|
|
d9d99f |
p[i++] = ch;
|
|
|
d9d99f |
@@ -397,10 +418,20 @@ parse_string (const char *str,
|
|
|
d9d99f |
switch (*ptr)
|
|
|
d9d99f |
{
|
|
|
d9d99f |
case '\\':
|
|
|
d9d99f |
- escaped = !escaped;
|
|
|
d9d99f |
- if (!escaped && put)
|
|
|
d9d99f |
- *(put++) = '\\';
|
|
|
d9d99f |
- ptr++;
|
|
|
d9d99f |
+ if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3)))
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ *(put++) = *ptr++;
|
|
|
d9d99f |
+ *(put++) = *ptr++;
|
|
|
d9d99f |
+ *(put++) = *ptr++;
|
|
|
d9d99f |
+ *(put++) = *ptr++;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
+ else
|
|
|
d9d99f |
+ {
|
|
|
d9d99f |
+ escaped = !escaped;
|
|
|
d9d99f |
+ if (!escaped && put)
|
|
|
d9d99f |
+ *(put++) = '\\';
|
|
|
d9d99f |
+ ptr++;
|
|
|
d9d99f |
+ }
|
|
|
d9d99f |
break;
|
|
|
d9d99f |
case '$':
|
|
|
d9d99f |
if (escaped)
|