diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index 7f546f95cd0eb..9655ecf296ae7 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -455,11 +455,18 @@ PHP_FUNCTION(bzcompress) RETURN_THROWS(); } + size_t chunk_len = source_len + (0.01 * source_len) + 600; + + if (chunk_len < source_len || chunk_len > UINT_MAX) { + zend_argument_value_error(1, "must be less than or equal to %lu", UINT_MAX); + RETURN_THROWS(); + } + /* Assign them to easy to use variables, dest_len is initially the length of the data + .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); + 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..727976bc67fda --- /dev/null +++ b/ext/bz2/tests/gh20620.phpt @@ -0,0 +1,18 @@ +--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 be less than or equal to %d