Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 32 additions & 6 deletions ext/standard/base64.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
#include "php.h"
#include "base64.h"

/* Private to this translation unit; C API callers retain existing flags. */
#define PHP_BASE64_FALLIBLE 2

/* {{{ base64 tables */
static const char base64_table[] = {
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
Expand Down Expand Up @@ -518,7 +521,11 @@ zend_string *php_base64_encode_avx512_vbmi(const unsigned char *str, size_t leng
unsigned char *o;
zend_string *result;

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
result = zend_string_safe_falloc(((length + 2) / 3), 4 * sizeof(char), 0, 0,
(flags & PHP_BASE64_FALLIBLE) != 0);
if (UNEXPECTED(result == NULL)) {
return NULL;
}
o = (unsigned char *)ZSTR_VAL(result);

const __m512i shuffle_splitting = _mm512_setr_epi32(
Expand Down Expand Up @@ -628,7 +635,11 @@ zend_string *php_base64_encode_avx512(const unsigned char *str, size_t length, z
unsigned char *o;
zend_string *result;

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
result = zend_string_safe_falloc(((length + 2) / 3), 4 * sizeof(char), 0, 0,
(flags & PHP_BASE64_FALLIBLE) != 0);
if (UNEXPECTED(result == NULL)) {
return NULL;
}
o = (unsigned char *)ZSTR_VAL(result);

while (length > 63) {
Expand Down Expand Up @@ -915,7 +926,11 @@ zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length, ze
unsigned char *o;
zend_string *result;

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
result = zend_string_safe_falloc(((length + 2) / 3), 4 * sizeof(char), 0, 0,
(flags & PHP_BASE64_FALLIBLE) != 0);
if (UNEXPECTED(result == NULL)) {
return NULL;
}
o = (unsigned char *)ZSTR_VAL(result);
# if defined(ZEND_INTRIN_AVX2_NATIVE) || defined(ZEND_INTRIN_AVX2_RESOLVER)
if (length > 31) {
Expand Down Expand Up @@ -956,7 +971,11 @@ zend_string *php_base64_encode_ssse3(const unsigned char *str, size_t length, ze
unsigned char *o;
zend_string *result;

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
result = zend_string_safe_falloc(((length + 2) / 3), 4 * sizeof(char), 0, 0,
(flags & PHP_BASE64_FALLIBLE) != 0);
if (UNEXPECTED(result == NULL)) {
return NULL;
}
o = (unsigned char *)ZSTR_VAL(result);

PHP_BASE64_ENCODE_SSSE3_LOOP;
Expand Down Expand Up @@ -1192,7 +1211,11 @@ PHPAPI zend_string *php_base64_encode_ex(const unsigned char *str, size_t length
unsigned char *p;
zend_string *result;

result = zend_string_safe_alloc(((length + 2) / 3), 4 * sizeof(char), 0, 0);
result = zend_string_safe_falloc(((length + 2) / 3), 4 * sizeof(char), 0, 0,
(flags & PHP_BASE64_FALLIBLE) != 0);
if (UNEXPECTED(result == NULL)) {
return NULL;
}
p = (unsigned char *)ZSTR_VAL(result);

p = php_base64_encode_impl(str, length, p, flags);
Expand Down Expand Up @@ -1238,7 +1261,10 @@ PHP_FUNCTION(base64_encode)
Z_PARAM_STRING(str, str_len)
ZEND_PARSE_PARAMETERS_END();

result = php_base64_encode((unsigned char*)str, str_len);
result = php_base64_encode_ex((unsigned char*)str, str_len, PHP_BASE64_FALLIBLE);
if (UNEXPECTED(result == NULL)) {
RETURN_OOM();
}
RETURN_STR(result);
}
/* }}} */
Expand Down
18 changes: 18 additions & 0 deletions ext/standard/tests/url/gh24492_base64_encode_oom.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
--TEST--
GH-24492: base64_encode() uses soft memory limit without hard-limit bailout
--INI--
memory_limit=16M
memory_hard_limit_percent=200
--FILE--
<?php
register_shutdown_function(static function (): void { echo "FB_SHUTDOWN\n"; });
$input = str_repeat('A', 13 * 1024 * 1024);
echo "FB_INPUT_READY\n";
base64_encode($input);
echo "UNREACHABLE\n";
?>
--EXPECTF--
FB_INPUT_READY

Fatal error: Allowed memory size of 16777216 bytes exhausted%s
FB_SHUTDOWN
Loading