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