From: Henrik Nordstrom Date: Wed, 4 Nov 2009 02:21:25 +0000 (+0100) Subject: Improve %nn parser X-Git-Tag: SQUID_3_2_0_1~620 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e0d6837cfce9d72b4bbaf51bed6e6eea76081eb3;p=thirdparty%2Fsquid.git Improve %nn parser --- diff --git a/lib/rfc1738.c b/lib/rfc1738.c index b202703f09..278a543052 100644 --- a/lib/rfc1738.c +++ b/lib/rfc1738.c @@ -177,30 +177,39 @@ 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) +rfc1738_unescape(char *s_) { - char hexnum[3]; + unsigned char *s = (unsigned char *) s_; 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); + 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]); + v2 = fromhex(s[j + 2]); + /* fromhex returns -1 on error which brings this out of range (|, not +) */ + x = v1 << 4 | v2; + if (x > 0 && x <= 255) { + s[i] = x; j += 2; } }