diff options
Diffstat (limited to 'lib/libc/src/base64.c')
-rw-r--r-- | lib/libc/src/base64.c | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/lib/libc/src/base64.c b/lib/libc/src/base64.c index 234d60d8..e3fd80d7 100644 --- a/lib/libc/src/base64.c +++ b/lib/libc/src/base64.c @@ -38,7 +38,8 @@ #include "plbase64.h" #include "prlog.h" /* For PR_NOT_REACHED */ #include "prmem.h" /* for malloc / PR_MALLOC */ -#include "plstr.h" /* for PL_strlen */ + +#include <string.h> /* for strlen */ static unsigned char *base = (unsigned char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; @@ -150,12 +151,24 @@ PL_Base64Encode { if( 0 == srclen ) { - srclen = PL_strlen(src); + size_t len = strlen(src); + srclen = len; + /* Detect truncation. */ + if( srclen != len ) + { + return (char *)0; + } } if( (char *)0 == dest ) { - PRUint32 destlen = ((srclen + 2)/3) * 4; + PRUint32 destlen; + /* Ensure all PRUint32 values stay within range. */ + if( srclen > (PR_UINT32_MAX/4) * 3 ) + { + return (char *)0; + } + destlen = ((srclen + 2)/3) * 4; dest = (char *)PR_MALLOC(destlen + 1); if( (char *)0 == dest ) { @@ -383,7 +396,13 @@ PL_Base64Decode if( 0 == srclen ) { - srclen = PL_strlen(src); + size_t len = strlen(src); + srclen = len; + /* Detect truncation. */ + if( srclen != len ) + { + return (char *)0; + } } if( srclen && (0 == (srclen & 3)) ) @@ -403,7 +422,8 @@ PL_Base64Decode if( (char *)0 == dest ) { - PRUint32 destlen = ((srclen * 3) / 4); + /* The following computes ((srclen * 3) / 4) without overflow. */ + PRUint32 destlen = (srclen / 4) * 3 + ((srclen % 4) * 3) / 4; dest = (char *)PR_MALLOC(destlen + 1); if( (char *)0 == dest ) { |