aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorSteve Holme <steve_holme@hotmail.com>2013-12-01 11:05:11 +0000
committerSteve Holme <steve_holme@hotmail.com>2013-12-01 11:12:23 +0000
commitc92c30edbde3b7f7562c2bcb4a06626781c55f1d (patch)
tree35dd53ca41b258aeee016752a31d28d7b3c366e2 /lib
parent4d10f486293ffa127cc6cd607e4c1af70c4f2282 (diff)
base64: Extended validation to look for invalid characters
Extended the basic validation in commit e17c1b25bc33eb to return a failure when invalid base64 characters are included.
Diffstat (limited to 'lib')
-rw-r--r--lib/base64.c60
1 files changed, 44 insertions, 16 deletions
diff --git a/lib/base64.c b/lib/base64.c
index a84e3be72..d0b49261a 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -40,22 +40,32 @@
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;