1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
This commit is contained in:
Christoph M. Becker
2016-07-05 16:59:20 +02:00
4 changed files with 57 additions and 30 deletions

View File

@@ -136,36 +136,45 @@ PHPAPI zend_string *php_base64_decode(const unsigned char *str, size_t length) /
PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length, zend_bool strict) /* {{{ */
{
const unsigned char *current = str;
int ch, i = 0, j = 0, k;
/* this sucks for threaded environments */
int ch, i = 0, j = 0, padding = 0;
zend_string *result;
result = zend_string_alloc(length, 0);
/* run through the whole string, converting as we go */
while ((ch = *current++) != '\0' && length-- > 0) {
while (length-- > 0) {
ch = *current++;
/* stop on null byte in non-strict mode (FIXME: is this really desired?) */
if (ch == 0 && !strict) {
break;
}
if (ch == base64_pad) {
if (*current != '=' && ((i % 4) == 1 || (strict && length > 0))) {
if ((i % 4) != 1) {
while (isspace(*(++current))) {
continue;
}
if (*current == '\0') {
continue;
}
}
/* fail if the padding character is second in a group (like V===) */
/* FIXME: why do we still allow invalid padding in other places in the middle of the string? */
if (i % 4 == 1) {
zend_string_free(result);
return NULL;
}
padding++;
continue;
}
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) {
zend_string_free(result);
return NULL;
if (!strict) {
/* skip unknown characters and whitespace */
if (ch < 0) {
continue;
}
} else {
/* skip whitespace */
if (ch == -1) {
continue;
}
/* fail on bad characters or if any data follows padding */
if (ch == -2 || padding) {
zend_string_free(result);
return NULL;
}
}
switch(i % 4) {
@@ -187,19 +196,6 @@ PHPAPI zend_string *php_base64_decode_ex(const unsigned char *str, size_t length
i++;
}
k = j;
/* mop things up if we ended on a boundary */
if (ch == base64_pad) {
switch(i % 4) {
case 1:
zend_string_free(result);
return NULL;
case 2:
k++;
case 3:
ZSTR_VAL(result)[k] = 0;
}
}
ZSTR_LEN(result) = j;
ZSTR_VAL(result)[ZSTR_LEN(result)] = '\0';

View File

@@ -0,0 +1,11 @@
--TEST--
Bug #72152 (base64_decode $strict fails to detect null byte)
--FILE--
<?php
var_dump(base64_decode("\x00", true));
var_dump(base64_decode("\x00VVVV", true));
var_dump(base64_decode("VVVV\x00", true));
--EXPECT--
bool(false)
bool(false)
bool(false)

View File

@@ -0,0 +1,13 @@
--TEST--
Bug #72263 (base64_decode skips a character after padding in strict mode)
--FILE--
<?php
var_dump(base64_decode("*", true));
var_dump(base64_decode("=*", true));
var_dump(base64_decode("VVV=", true));
var_dump(base64_decode("VVV=*", true));
--EXPECT--
bool(false)
bool(false)
string(2) "UU"
bool(false)

View File

@@ -0,0 +1,7 @@
--TEST--
Bug #72264 (base64_decode $strict fails with whitespace between padding)
--FILE--
<?php
var_dump(base64_decode("VV= =", true));
--EXPECT--
string(1) "U"