summaryrefslogtreecommitdiff
path: root/ext/standard/base64.c
diff options
context:
space:
mode:
authorMoriyoshi Koizumi <moriyoshi@php.net>2003-06-04 14:41:45 +0000
committerMoriyoshi Koizumi <moriyoshi@php.net>2003-06-04 14:41:45 +0000
commit12ecc6ca1e523a5d2e92297d43ba8f1f7a72e66f (patch)
tree448369a92d02c5fc14ddf46510da868e91b58549 /ext/standard/base64.c
parent0f1f635d00c6c495cc196b2e013ead9e14a7cd09 (diff)
downloadphp-git-12ecc6ca1e523a5d2e92297d43ba8f1f7a72e66f.tar.gz
Fixed base64_encode() integer overflow issue pointed out in TODO_SEGFAULTS
Diffstat (limited to 'ext/standard/base64.c')
-rw-r--r--ext/standard/base64.c49
1 files changed, 29 insertions, 20 deletions
diff --git a/ext/standard/base64.c b/ext/standard/base64.c
index 2449fef373..ba2375eaaa 100644
--- a/ext/standard/base64.c
+++ b/ext/standard/base64.c
@@ -52,18 +52,28 @@ static const short base64_reverse_table[256] = {
};
/* }}} */
-/* {{{ */
+/* {{{ php_base64_encode */
PHPAPI unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length)
{
const unsigned char *current = str;
- int i = 0;
- unsigned char *result = (unsigned char *)emalloc(((length + 3 - length % 3) * 4 / 3 + 1) * sizeof(char));
+ unsigned char *p;
+ unsigned char *result;
+
+ if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
+ if (ret_length != NULL) {
+ *ret_length = 0;
+ }
+ return NULL;
+ }
+
+ result = (unsigned char *)safe_emalloc(((length + 2) / 3) * 4, sizeof(char), 1);
+ p = result;
while (length > 2) { /* keep going until we have less than 24 bits */
- result[i++] = base64_table[current[0] >> 2];
- result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
- result[i++] = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
- result[i++] = base64_table[current[2] & 0x3f];
+ *p++ = base64_table[current[0] >> 2];
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
+ *p++ = base64_table[current[2] & 0x3f];
current += 3;
length -= 3; /* we just handle 3 octets of data */
@@ -71,22 +81,21 @@ PHPAPI unsigned char *php_base64_encode(const unsigned char *str, int length, in
/* now deal with the tail end of things */
if (length != 0) {
- result[i++] = base64_table[current[0] >> 2];
+ *p++ = base64_table[current[0] >> 2];
if (length > 1) {
- result[i++] = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
- result[i++] = base64_table[(current[1] & 0x0f) << 2];
- result[i++] = base64_pad;
- }
- else {
- result[i++] = base64_table[(current[0] & 0x03) << 4];
- result[i++] = base64_pad;
- result[i++] = base64_pad;
+ *p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
+ *p++ = base64_table[(current[1] & 0x0f) << 2];
+ *p++ = base64_pad;
+ } else {
+ *p++ = base64_table[(current[0] & 0x03) << 4];
+ *p++ = base64_pad;
+ *p++ = base64_pad;
}
}
- if(ret_length) {
- *ret_length = i;
+ if (ret_length != NULL) {
+ *ret_length = (int)(p - result);
}
- result[i] = '\0';
+ *p = '\0';
return result;
}
/* }}} */
@@ -125,7 +134,7 @@ void php_base64_init()
*/
/* }}} */
-/* {{{ */
+/* {{{ php_base64_decode */
/* as above, but backwards. :) */
PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length)
{