]> granicus.if.org Git - curl/commitdiff
base64: Extended validation to look for invalid characters
authorSteve Holme <steve_holme@hotmail.com>
Sun, 1 Dec 2013 11:05:11 +0000 (11:05 +0000)
committerSteve Holme <steve_holme@hotmail.com>
Sun, 1 Dec 2013 11:12:23 +0000 (11:12 +0000)
Extended the basic validation in commit e17c1b25bc33eb to return a
failure when invalid base64 characters are included.

lib/base64.c
tests/unit/unit1302.c

index a84e3be72c915ceca1f7f745d313e58b949cd7d0..d0b49261ab6f703e233fa080bf3682cbe3e0f4c9 100644 (file)
 static const char table64[]=
   "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-static void decodeQuantum(unsigned char *dest, const char *src)
+static size_t decodeQuantum(unsigned char *dest, const char *src)
 {
+  size_t padding = 0;
   const char *s, *p;
   unsigned long i, v, x = 0;
 
   for(i = 0, s = src; i < 4; i++, s++) {
     v = 0;
-    p = table64;
-    while(*p && (*p != *s)) {
-      v++;
-      p++;
-    }
-    if(*p == *s)
-      x = (x << 6) + v;
-    else if(*s == '=')
+
+    if(*s == '=') {
       x = (x << 6);
+      padding++;
+    }
+    else {
+      p = table64;
+
+      while(*p && (*p != *s)) {
+        v++;
+        p++;
+      }
+
+      if(*p == *s)
+        x = (x << 6) + v;
+      else
+        return 0;
+    }
   }
 
   dest[2] = curlx_ultouc(x & 0xFFUL);
@@ -63,6 +73,8 @@ static void decodeQuantum(unsigned char *dest, const char *src)
   dest[1] = curlx_ultouc(x & 0xFFUL);
   x >>= 8;
   dest[0] = curlx_ultouc(x & 0xFFUL);
+
+  return 3 - padding;
 }
 
 /*
@@ -86,9 +98,11 @@ CURLcode Curl_base64_decode(const char *src,
   size_t length = 0;
   size_t equalsTerm = 0;
   size_t i;
+  size_t result;
   size_t numQuantums;
   unsigned char lastQuantum[3];
   size_t rawlen = 0;
+  unsigned char *pos;
   unsigned char *newstr;
 
   *outptr = NULL;
@@ -125,24 +139,38 @@ CURLcode Curl_base64_decode(const char *src,
   if(!newstr)
     return CURLE_OUT_OF_MEMORY;
 
-  *outptr = newstr;
+  pos = newstr;
 
   /* Decode all but the last quantum (which may not decode to a
   multiple of 3 bytes) */
   for(i = 0; i < numQuantums - 1; i++) {
-    decodeQuantum(newstr, src);
-    newstr += 3; src += 4;
+    result = decodeQuantum(pos, src);
+    if(!result) {
+      Curl_safefree(newstr);
+
+      return CURLE_BAD_CONTENT_ENCODING;
+    }
+
+    pos += result;
+    src += 4;
   }
 
   /* Decode the last quantum */
-  decodeQuantum(lastQuantum, src);
+  result = decodeQuantum(lastQuantum, src);
+  if(!result) {
+    Curl_safefree(newstr);
+
+    return CURLE_BAD_CONTENT_ENCODING;
+  }
+
   for(i = 0; i < 3 - equalsTerm; i++)
-    newstr[i] = lastQuantum[i];
+    pos[i] = lastQuantum[i];
 
   /* Zero terminate */
-  newstr[i] = '\0';
+  pos[i] = '\0';
 
-  /* Return the size of decoded data */
+  /* Return the decoded data */
+  *outptr = newstr;
   *outlen = rawlen;
 
   return CURLE_OK;
index b5688f047749822767b84deee094a398e78cd321..6886af8c49d1d3b7f3f88b59b399884eb5f4973b 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
  *
  * This software is licensed as described in the file COPYING, which
  * you should have received as part of this distribution. The terms
@@ -31,7 +31,7 @@ static struct SessionHandle *data;
 static CURLcode unit_setup( void )
 {
   data = curl_easy_init();
-  if (!data)
+  if(!data)
     return CURLE_OUT_OF_MEMORY;
   return CURLE_OK;
 }
@@ -128,13 +128,12 @@ fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_C
 fail_unless(size == 0, "size should be 0");
 fail_if(decoded, "returned pointer should be NULL");
 
-/* this is garbage input that libcurl decodes as far as possible */
-size = 0;
-decoded = NULL;
+/* This is garbage input as it contains an illegal base64 character */
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
 rc = Curl_base64_decode("a\x1f==", &decoded, &size);
-fail_unless(rc == CURLE_OK, "return code should be CURLE_OK");
-fail_unless(size == 1, "size should be 1");
-fail_if(!decoded, "returned pointer should not be NULL");
-Curl_safefree(decoded);
+fail_unless(rc == CURLE_BAD_CONTENT_ENCODING, "return code should be CURLE_BAD_CONTENT_ENCODING");
+fail_unless(size == 0, "size should be 0");
+fail_if(decoded, "returned pointer should be NULL");
 
 UNITTEST_STOP