From: Amos Jeffries Date: Sat, 14 Nov 2009 23:28:12 +0000 (+1300) Subject: Author: Henrik Nordstrom X-Git-Tag: SQUID_3_0_STABLE21~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3f25885018cf57827f1d754a619ca45a4ad9628d;p=thirdparty%2Fsquid.git Author: Henrik Nordstrom Improve %nn parser --- diff --git a/lib/rfc1738.c b/lib/rfc1738.c index 1ea1a765e7..b5107101dd 100644 --- a/lib/rfc1738.c +++ b/lib/rfc1738.c @@ -179,33 +179,44 @@ rfc1738_escape_part(const char *url) * rfc1738_unescape() - Converts escaped characters (%xy numbers) in * given the string. %% is a %. %ab is the 8-bit hexadecimal number "ab" */ +static inline int +fromhex(char ch) +{ + if (ch >= '0' && ch <= '9') + return ch - '0'; + if (ch >= 'a' && ch <= 'f') + return ch - 'a' + 10; + if (ch >= 'A' && ch <= 'F') + return ch - 'A' + 10; + return -1; +} + void rfc1738_unescape(char *s) { - char hexnum[3]; int i, j; /* i is write, j is read */ - unsigned int x; for (i = j = 0; s[j]; i++, j++) { - s[i] = s[j]; - if (s[i] != '%') - continue; - if (s[j + 1] == '%') { /* %% case */ - j++; - continue; - } - if (s[j + 1] && s[j + 2]) { - if (s[j + 1] == '0' && s[j + 2] == '0') { /* %00 case */ - j += 2; - continue; - } - hexnum[0] = s[j + 1]; - hexnum[1] = s[j + 2]; - hexnum[2] = '\0'; - if (1 == sscanf(hexnum, "%x", &x)) { - s[i] = (char) (0x0ff & x); - j += 2; - } - } + s[i] = s[j]; + if (s[j] != '%') { + /* normal case, nothing more to do */ + } else if (s[j + 1] == '%') { /* %% case */ + j++; /* Skip % */ + } else { + /* decode */ + char v1, v2; + int x; + v1 = fromhex(s[j + 1]); + if (v1 < 0) + continue; /* non-hex or \0 */ + v2 = fromhex(s[j + 2]); + if (v2 < 0) + continue; /* non-hex or \0 */ + x = v1 << 4 | v2; + if (x > 0 && x <= 255) { + s[i] = x; + j += 2; + } + } } s[i] = '\0'; }