aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/base64.c19
-rw-r--r--tests/unit/unit1302.c20
2 files changed, 33 insertions, 6 deletions
diff --git a/lib/base64.c b/lib/base64.c
index 3f3f0f9b8..2a7add189 100644
--- a/lib/base64.c
+++ b/lib/base64.c
@@ -82,6 +82,7 @@ static void decodeQuantum(unsigned char *dest, const char *src)
CURLcode Curl_base64_decode(const char *src,
unsigned char **outptr, size_t *outlen)
{
+ size_t srcLen = 0;
size_t length = 0;
size_t equalsTerm = 0;
size_t i;
@@ -92,21 +93,31 @@ CURLcode Curl_base64_decode(const char *src,
*outptr = NULL;
*outlen = 0;
+ srcLen = strlen(src);
+ /* Check the length of the input string is valid */
+ if(!srcLen || srcLen % 4)
+ return CURLE_BAD_CONTENT_ENCODING;
+
+ /* Find the position of any = padding characters */
while((src[length] != '=') && src[length])
length++;
+
/* A maximum of two = padding characters is allowed */
if(src[length] == '=') {
equalsTerm++;
if(src[length+equalsTerm] == '=')
equalsTerm++;
}
- numQuantums = (length + equalsTerm) / 4;
+
+ /* Check the = padding characters weren't part way through the input */
+ if(length + equalsTerm != srcLen)
+ return CURLE_BAD_CONTENT_ENCODING;
- /* Don't allocate a buffer if the decoded length is 0 */
- if(numQuantums == 0)
- return CURLE_OK;
+ /* Calculate the number of quantums */
+ numQuantums = (length + equalsTerm) / 4;
+ /* Calculate the size of the decoded string */
rawlen = (numQuantums * 3) - equalsTerm;
/* The buffer must be large enough to make room for the last quantum
diff --git a/tests/unit/unit1302.c b/tests/unit/unit1302.c
index fc50c8865..b5688f047 100644
--- a/tests/unit/unit1302.c
+++ b/tests/unit/unit1302.c
@@ -104,11 +104,27 @@ fail_unless(size == 1, "size should be 1");
verify_memory(decoded, "i", 2);
Curl_safefree(decoded);
-/* this is an illegal input */
+/* This is illegal input as the data is too short */
size = 1; /* not zero */
decoded = &anychar; /* not NULL */
rc = Curl_base64_decode("aQ", &decoded, &size);
-/* return code indiferent, but output shall be as follows */
+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");
+
+/* This is illegal input as it contains three padding characters */
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
+rc = Curl_base64_decode("a===", &decoded, &size);
+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");
+
+/* This is illegal input as it contains a padding character mid input */
+size = 1; /* not zero */
+decoded = &anychar; /* not NULL */
+rc = Curl_base64_decode("a=Q=", &decoded, &size);
+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");