]> git.ipfire.org Git - thirdparty/squid.git/commitdiff
Improve %nn parser
authorHenrik Nordstrom <henrik@henriknordstrom.net>
Wed, 4 Nov 2009 02:21:25 +0000 (03:21 +0100)
committerHenrik Nordstrom <henrik@henriknordstrom.net>
Wed, 4 Nov 2009 02:21:25 +0000 (03:21 +0100)
lib/rfc1738.c

index b202703f0926f02008570dc61842c34dd61f6c6c..278a543052c461e041d6117281ff7670b8f69040 100644 (file)
@@ -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;
             }
         }