From c9df292a2906c38fafb39e81bacdce6748473784 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 29 Nov 2025 21:32:19 +0000 Subject: [PATCH] Fix GH-20620: bzcompress() overflow on large source size. close GH-20621 --- ext/bz2/bz2.c | 10 +++++++++- ext/bz2/tests/gh20620.phpt | 21 +++++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 ext/bz2/tests/gh20620.phpt diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index 7f546f95cd0eb..060a2df640048 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -459,7 +459,15 @@ PHP_FUNCTION(bzcompress) + .01 x length of data + 600 which is the largest size the results of the compression could possibly be, at least that's what the libbz2 docs say (thanks to jeremy@nirvani.net for pointing this out). */ - dest_len = (unsigned int) (source_len + (0.01 * source_len) + 600); + size_t chunk_len = source_len + source_len / 100 + 600; + const size_t min = MIN(ZSTR_MAX_LEN, UINT_MAX); + + if (chunk_len < source_len || chunk_len > min) { + zend_argument_value_error(1, "must have a length less than or equal to %zu", min); + RETURN_THROWS(); + } + + dest_len = (unsigned int) chunk_len; /* Allocate the destination buffer */ dest = zend_string_alloc(dest_len, 0); diff --git a/ext/bz2/tests/gh20620.phpt b/ext/bz2/tests/gh20620.phpt new file mode 100644 index 0000000000000..351ba488b2bd6 --- /dev/null +++ b/ext/bz2/tests/gh20620.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug GH-20620 (bzcompress with large source) +--EXTENSIONS-- +bz2 +--SKIPIF-- + +--INI-- +memory_limit=-1 +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECTF-- +bzcompress(): Argument #1 ($data) must have a length less than or equal to %d