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