a5bd9f6
From a20c29e7b8c9b92fc8919968a2382737d6662695 Mon Sep 17 00:00:00 2001
c849461
From: Peter Jones <pjones@redhat.com>
c849461
Date: Mon, 1 Oct 2012 13:24:37 -0400
a5bd9f6
Subject: [PATCH 351/364] Pass "\x[[:hex:]][[:hex:]]" straight through
a5bd9f6
 unmolested.
c849461
c849461
---
09ea065
 grub-core/commands/wildcard.c | 16 +++++++++++++++-
a5bd9f6
 grub-core/lib/cmdline.c       | 34 ++++++++++++++++++++++++++++++++--
a5bd9f6
 grub-core/script/execute.c    | 43 +++++++++++++++++++++++++++++++++++++------
a5bd9f6
 3 files changed, 84 insertions(+), 9 deletions(-)
c849461
c849461
diff --git a/grub-core/commands/wildcard.c b/grub-core/commands/wildcard.c
a5bd9f6
index 2807f80..0f40e04 100644
c849461
--- a/grub-core/commands/wildcard.c
c849461
+++ b/grub-core/commands/wildcard.c
a5bd9f6
@@ -458,6 +458,12 @@ check_file (const char *dir, const char *basename)
a5bd9f6
   return ctx.found;
c849461
 }
c849461
 
c849461
+static int
c849461
+is_hex(char c)
c849461
+{
c849461
+  return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
c849461
+}
c849461
+
c849461
 static void
c849461
 unescape (char *out, const char *in, const char *end)
c849461
 {
a5bd9f6
@@ -466,7 +472,15 @@ unescape (char *out, const char *in, const char *end)
c849461
 
c849461
   for (optr = out, iptr = in; iptr < end;)
c849461
     {
c849461
-      if (*iptr == '\\' && iptr + 1 < end)
c849461
+      if (*iptr == '\\' && iptr + 3 < end && iptr[1] == 'x' && is_hex(iptr[2]) && is_hex(iptr[3]))
c849461
+	{
09ea065
+	  *optr++ = *iptr++;
09ea065
+	  *optr++ = *iptr++;
09ea065
+	  *optr++ = *iptr++;
09ea065
+	  *optr++ = *iptr++;
c849461
+	  continue;
c849461
+	}
c849461
+      else if (*iptr == '\\' && iptr + 1 < end)
c849461
 	{
c849461
 	  *optr++ = iptr[1];
c849461
 	  iptr += 2;
c849461
diff --git a/grub-core/lib/cmdline.c b/grub-core/lib/cmdline.c
09ea065
index a702e64..c8605a7 100644
c849461
--- a/grub-core/lib/cmdline.c
c849461
+++ b/grub-core/lib/cmdline.c
c849461
@@ -20,6 +20,12 @@
c849461
 #include <grub/lib/cmdline.h>
c849461
 #include <grub/misc.h>
c849461
 
c849461
+static int
c849461
+is_hex(char c)
c849461
+{
c849461
+  return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
c849461
+}
c849461
+
c849461
 static unsigned int check_arg (char *c, int *has_space)
c849461
 {
c849461
   int space = 0;
c849461
@@ -27,7 +33,13 @@ static unsigned int check_arg (char *c, int *has_space)
c849461
 
c849461
   while (*c)
c849461
     {
c849461
-      if (*c == '\\' || *c == '\'' || *c == '"')
c849461
+      if (*c == '\\' && *(c+1) == 'x' && is_hex(*(c+2)) && is_hex(*(c+3)))
c849461
+	{
c849461
+	  size += 4;
c849461
+	  c += 4;
c849461
+	  continue;
c849461
+	}
c849461
+      else if (*c == '\\' || *c == '\'' || *c == '"')
c849461
 	size++;
c849461
       else if (*c == ' ')
c849461
 	space = 1;
09ea065
@@ -82,7 +94,25 @@ int grub_create_loader_cmdline (int argc, char *argv[], char *buf,
c849461
 
c849461
       while (*c)
c849461
 	{
c849461
-	  if (*c == '\\' || *c == '\'' || *c == '"')
09ea065
+	  if (*c == ' ')
c849461
+	    {
c849461
+	      *buf++ = '\\';
c849461
+	      *buf++ = 'x';
09ea065
+	      *buf++ = '2';
09ea065
+	      *buf++ = '0';
c849461
+	      c++;
c849461
+	      continue;
c849461
+	    }
09ea065
+	  else if (*c == '\\' && *(c+1) == 'x' &&
09ea065
+		   is_hex(*(c+2)) && is_hex(*(c+3)))
c849461
+	    {
09ea065
+	      *buf++ = *c++;
09ea065
+	      *buf++ = *c++;
09ea065
+	      *buf++ = *c++;
09ea065
+	      *buf++ = *c++;
c849461
+	      continue;
c849461
+	    }
c849461
+	  else if (*c == '\\' || *c == '\'' || *c == '"')
c849461
 	    *buf++ = '\\';
c849461
 
c849461
 	  *buf++ = *c;
c849461
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
a5bd9f6
index a1dcc34..686e1fa 100644
c849461
--- a/grub-core/script/execute.c
c849461
+++ b/grub-core/script/execute.c
09ea065
@@ -52,6 +52,12 @@ static struct grub_script_scope *scope = 0;
c849461
 /* Wildcard translator for GRUB script.  */
c849461
 struct grub_script_wildcard_translator *grub_wildcard_translator;
c849461
 
c849461
+static int
c849461
+is_hex(char c)
c849461
+{
c849461
+  return ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
c849461
+}
c849461
+
c849461
 static char*
c849461
 wildcard_escape (const char *s)
c849461
 {
09ea065
@@ -68,7 +74,15 @@ wildcard_escape (const char *s)
c849461
   i = 0;
c849461
   while ((ch = *s++))
c849461
     {
c849461
-      if (ch == '*' || ch == '\\' || ch == '?')
09ea065
+      if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
c849461
+	{
09ea065
+	  p[i++] = ch;
09ea065
+	  p[i++] = *s++;
09ea065
+	  p[i++] = *s++;
09ea065
+	  p[i++] = *s++;
c849461
+	  continue;
c849461
+	}
c849461
+      else if (ch == '*' || ch == '\\' || ch == '?')
c849461
 	p[i++] = '\\';
c849461
       p[i++] = ch;
c849461
     }
09ea065
@@ -92,7 +106,14 @@ wildcard_unescape (const char *s)
c849461
   i = 0;
c849461
   while ((ch = *s++))
c849461
     {
c849461
-      if (ch == '\\')
c849461
+      if (ch == '\\' && s[0] == 'x' && is_hex(s[1]) && is_hex(s[2]))
c849461
+	{
09ea065
+	  p[i++] = '\\';
09ea065
+	  p[i++] = *s++;
09ea065
+	  p[i++] = *s++;
09ea065
+	  p[i++] = *s++;
c849461
+	}
c849461
+      else if (ch == '\\')
c849461
 	p[i++] = *s++;
c849461
       else
c849461
 	p[i++] = ch;
a5bd9f6
@@ -394,10 +415,20 @@ parse_string (const char *str,
c849461
     switch (*ptr)
c849461
       {
c849461
       case '\\':
c849461
-	escaped = !escaped;
c849461
-	if (!escaped && put)
a5bd9f6
-	  *(put++) = '\\';
c849461
-	ptr++;
09ea065
+	if (!escaped && put && *(ptr+1) == 'x' && is_hex(*(ptr+2)) && is_hex(*(ptr+3)))
c849461
+	  {
a5bd9f6
+	    *(put++) = *ptr++;
a5bd9f6
+	    *(put++) = *ptr++;
a5bd9f6
+	    *(put++) = *ptr++;
a5bd9f6
+	    *(put++) = *ptr++;
c849461
+	  }
c849461
+	else
c849461
+	  {
c849461
+	    escaped = !escaped;
c849461
+	    if (!escaped && put)
a5bd9f6
+	      *(put++) = '\\';
c849461
+	    ptr++;
c849461
+	  }
c849461
 	break;
c849461
       case '$':
c849461
 	if (escaped)
c849461
-- 
a5bd9f6
1.8.1.4
c849461