/*
+----------------------------------------------------------------------+
| PHP Version 5 |
+----------------------------------------------------------------------+
| Copyright (c) 1997-2008 The PHP Group |
+----------------------------------------------------------------------+
| This source file is subject to version 3.01 of the PHP license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.php.net/license/3_01.txt |
| If you did not receive a copy of the PHP license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: Jim Winstead <jimw@php.net> |
+----------------------------------------------------------------------+
*/
/* $Id: base64.c,v 1.43.2.2.2.4 2007/12/31 07:20:12 sebastian Exp $ */
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 */
*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 */
}
/* now deal with the tail end of things */
if (length != 0) {
*p++ = base64_table[current[0] >> 2];
if (length > 1) {
*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 != NULL) {
*ret_length = (int)(p - result);
}
*p = '\0';
return result;
}
/* }}} */
/* {{{ */
/* generate reverse table (do not set index 0 to 64)
static unsigned short base64_reverse_table[256];
#define rt base64_reverse_table
void php_base64_init(void)
{
char *s = emalloc(10240), *sp;
char *chp;
short idx;
PHPAPI unsigned char *php_base64_decode(const unsigned char *str, int length, int *ret_length)
{
return php_base64_decode_ex(str, length, ret_length, 0);
}
/* {{{ php_base64_decode */
/* as above, but backwards. :) */
PHPAPI unsigned char *php_base64_decode_ex(const unsigned char *str, int length, int *ret_length, zend_bool strict)
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
/* this sucks for threaded environments */
unsigned char *result;
result = (unsigned char *)emalloc(length + 1);
/* run through the whole string, converting as we go */
while ((ch = *current++) != '\0' && length-- > 0) {
if (ch == base64_pad) break;
ch = base64_reverse_table[ch];
if ((!strict && ch < 0) || ch == -1) { /* a space or some other separator character, we simply skip over */
continue;
} else if (ch == -2) {
efree(result);
return NULL;
}
k = j;
/* mop things up if we ended on a boundary */
if (ch == base64_pad) {
switch(i % 4) {
case 1:
efree(result);
return NULL;
case 2:
k++;
case 3:
result[k++] = 0;
}
}
if(ret_length) {
*ret_length = j;
}
result[j] = '\0';
return result;
}
/* }}} */
/* {{{ proto string base64_encode(string str)
Encodes string using MIME base64 algorithm */
PHP_FUNCTION(base64_encode)
{
char *str;
unsigned char *result;
int str_len, ret_length;