Commit fb76b3d7158 for php.net
commit fb76b3d7158647d2c96fdcf2f5a2feb01d04b425
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Sat Jun 20 21:26:09 2026 -0400
ext/zlib: honor preset dictionary for raw inflate with non-default window
inflate_init() applies the preset dictionary eagerly for raw streams via
inflateSetDictionary(), gated on encoding == PHP_ZLIB_ENCODING_RAW. But
encoding is first adjusted by the window size (encoding += 15 - window),
so a raw stream with a non-default window no longer equals
PHP_ZLIB_ENCODING_RAW and the dictionary is silently dropped; raw streams
carry no header and never emit Z_NEED_DICT, so inflate_add()'s deferred
path never applies it either. Gate on the pre-adjustment encoding. The
deflate side already applies the dictionary unconditionally, so the
roundtrip was broken for this case.
Closes GH-22381
diff --git a/NEWS b/NEWS
index 39010ac77b1..41e9dd50699 100644
--- a/NEWS
+++ b/NEWS
@@ -62,6 +62,10 @@ PHP NEWS
PROCESS_INFORMATION, an indeterminate comspec pointer after a failed
lookup, and an unchecked CreateFileA() failure. (Ilia Alshanetsky)
+- Zlib:
+ . Fixed inflate_init() dropping the preset dictionary for raw streams with
+ a non-default window. (Ilia Alshanetsky)
+
24 Sep 2026, PHP 8.5.11
diff --git a/ext/zlib/tests/inflate_raw_dictionary_window.phpt b/ext/zlib/tests/inflate_raw_dictionary_window.phpt
new file mode 100644
index 00000000000..0269127c136
--- /dev/null
+++ b/ext/zlib/tests/inflate_raw_dictionary_window.phpt
@@ -0,0 +1,20 @@
+--TEST--
+inflate_init(): preset dictionary is honored for raw encoding with a non-default window
+--EXTENSIONS--
+zlib
+--FILE--
+<?php
+$dict = "the quick brown fox jumps over the lazy dog";
+$data = str_repeat($dict . " ", 8);
+$opts = ['window' => 10, 'dictionary' => $dict];
+
+$def = deflate_init(ZLIB_ENCODING_RAW, $opts);
+$comp = deflate_add($def, $data, ZLIB_FINISH);
+
+$inf = inflate_init(ZLIB_ENCODING_RAW, $opts);
+$out = inflate_add($inf, $comp, ZLIB_FINISH);
+
+var_dump($out === $data);
+?>
+--EXPECT--
+bool(true)
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index b221b1f4b55..003ffa80111 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -904,6 +904,7 @@ PHP_FUNCTION(inflate_init)
ctx->inflateDictlen = dictlen;
ctx->status = Z_OK;
+ zend_long orig_encoding = encoding;
if (encoding < 0) {
encoding += 15 - window;
} else {
@@ -917,7 +918,7 @@ PHP_FUNCTION(inflate_init)
RETURN_FALSE;
}
- if (encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) {
+ if (orig_encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) {
switch (inflateSetDictionary(&ctx->Z, (Bytef *) ctx->inflateDict, ctx->inflateDictlen)) {
case Z_OK:
efree(ctx->inflateDict);