Commit 15d58caa797 for php.net

commit 15d58caa79753525f70e100ce25a468a7c7b8fca
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date:   Thu Jun 25 09:18:44 2026 -0400

    Fix unsigned wrap in bzdecompress() output realloc at source_len UINT_MAX (#22432)

    The input guard rejects only source_len > UINT_MAX, so source_len ==
    UINT_MAX is permitted and assigned to bzs.avail_out (unsigned int). The
    per-iteration realloc then computed bzs.avail_out+1 in unsigned int
    arithmetic, which wraps to 0 at UINT_MAX, allocating no headroom while
    bz2 still believes avail_out bytes are available at next_out: the next
    decompress round writes past the buffer. Compute the term as
    (size_t)bzs.avail_out + 1 so the increment is done in size_t and cannot
    wrap, matching the (size_t) casts already used on the same call.

diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c
index 512632fe8a2..6af8286c533 100644
--- a/ext/bz2/bz2.c
+++ b/ext/bz2/bz2.c
@@ -544,7 +544,7 @@ PHP_FUNCTION(bzdecompress)
 			/* no reason to continue if we're going to drop it anyway */
 			break;
 		}
-		dest = zend_string_safe_realloc(dest, 1, bzs.avail_out+1, (size_t) size, 0);
+		dest = zend_string_safe_realloc(dest, 1, (size_t) bzs.avail_out + 1, (size_t) size, 0);
 		bzs.next_out = ZSTR_VAL(dest) + size;
 	}