diff options
-rw-r--r-- | lib/base64.c | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/lib/base64.c b/lib/base64.c index 54e4ed5d7..98b281309 100644 --- a/lib/base64.c +++ b/lib/base64.c @@ -93,24 +93,38 @@ size_t Curl_base64_decode(const char *src, unsigned char **outptr) while((src[length] != '=') && src[length]) length++; - while(src[length+equalsTerm] == '=') + /* A maximum of two = padding characters is allowed */ + if(src[length] == '=') { equalsTerm++; - + if(src[length+equalsTerm] == '=') + equalsTerm++; + } numQuantums = (length + equalsTerm) / 4; + /* Don't allocate a buffer if the decoded length is 0 */ + if (numQuantums <= 0) + return 0; + rawlen = (numQuantums * 3) - equalsTerm; - newstr = malloc(rawlen+1); + /* The buffer must be large enough to make room for the last quantum + (which may be partially thrown out) and the zero terminator. */ + newstr = malloc(rawlen+4); if(!newstr) return 0; *outptr = 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((unsigned char *)newstr, src); newstr += 3; src += 4; } + /* This final decode may actually read slightly past the end of the buffer + if the input string is missing pad bytes. This will almost always be + harmless. */ decodeQuantum(lastQuantum, src); for(i = 0; i < 3 - equalsTerm; i++) newstr[i] = lastQuantum[i]; |