1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

bz2: Fix truncation of total output size causing erroneous errors

Also switch to uint64_t as that's used on master and makes the code
simpler to fix.

Closes GH-20807.

Co-authored-by: Arnaud Le Blanc <arnaud.lb@gmail.com>
This commit is contained in:
Niels Dossche
2025-12-31 00:06:35 +01:00
committed by ndossche
parent f8114f554c
commit 4ee95fc2f3
3 changed files with 26 additions and 13 deletions

3
NEWS
View File

@@ -2,6 +2,9 @@ PHP NEWS
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
?? ??? ????, PHP 8.4.20
- Bz2:
. Fix truncation of total output size causing erroneous errors. (ndossche)
- PCRE:
. Fixed re-entrancy issue on php_pcre_match_impl, php_pcre_replace_impl,
php_pcre_split_impl, and php_pcre_grep_impl. (David Carlier)

View File

@@ -502,11 +502,7 @@ PHP_FUNCTION(bzdecompress)
size_t source_len;
int error;
bool small = 0;
#ifdef PHP_WIN32
unsigned __int64 size = 0;
#else
unsigned long long size = 0;
#endif
uint64_t size = 0;
bz_stream bzs;
if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS(), "s|b", &source, &source_len, &small)) {
@@ -531,27 +527,22 @@ PHP_FUNCTION(bzdecompress)
while ((error = BZ2_bzDecompress(&bzs)) == BZ_OK && bzs.avail_in > 0) {
/* compression is better then 2:1, need to allocate more memory */
bzs.avail_out = source_len;
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
#ifndef ZEND_ENABLE_ZVAL_LONG64
size = (((uint64_t) bzs.total_out_hi32) << 32U) + bzs.total_out_lo32;
if (size > SIZE_MAX) {
/* no reason to continue if we're going to drop it anyway */
break;
}
#endif
dest = zend_string_safe_realloc(dest, 1, bzs.avail_out+1, (size_t) size, 0);
bzs.next_out = ZSTR_VAL(dest) + size;
}
if (error == BZ_STREAM_END || error == BZ_OK) {
size = (bzs.total_out_hi32 * (unsigned int) -1) + bzs.total_out_lo32;
#ifndef ZEND_ENABLE_ZVAL_LONG64
size = (((uint64_t) bzs.total_out_hi32) << 32U) + bzs.total_out_lo32;
if (UNEXPECTED(size > SIZE_MAX)) {
php_error_docref(NULL, E_WARNING, "Decompressed size too big, max is %zd", SIZE_MAX);
zend_string_efree(dest);
RETVAL_LONG(BZ_MEM_ERROR);
} else
#endif
{
} else {
dest = zend_string_safe_realloc(dest, 1, (size_t)size, 1, 0);
ZSTR_LEN(dest) = (size_t)size;
ZSTR_VAL(dest)[(size_t)size] = '\0';

File diff suppressed because one or more lines are too long