Skip to content

Commit fb76b3d

Browse files
committed
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
1 parent c091db1 commit fb76b3d

3 files changed

Lines changed: 26 additions & 1 deletion

File tree

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,10 @@ PHP NEWS
6262
PROCESS_INFORMATION, an indeterminate comspec pointer after a failed
6363
lookup, and an unchecked CreateFileA() failure. (Ilia Alshanetsky)
6464

65+
- Zlib:
66+
. Fixed inflate_init() dropping the preset dictionary for raw streams with
67+
a non-default window. (Ilia Alshanetsky)
68+
6569

6670
24 Sep 2026, PHP 8.5.11
6771

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
inflate_init(): preset dictionary is honored for raw encoding with a non-default window
3+
--EXTENSIONS--
4+
zlib
5+
--FILE--
6+
<?php
7+
$dict = "the quick brown fox jumps over the lazy dog";
8+
$data = str_repeat($dict . " ", 8);
9+
$opts = ['window' => 10, 'dictionary' => $dict];
10+
11+
$def = deflate_init(ZLIB_ENCODING_RAW, $opts);
12+
$comp = deflate_add($def, $data, ZLIB_FINISH);
13+
14+
$inf = inflate_init(ZLIB_ENCODING_RAW, $opts);
15+
$out = inflate_add($inf, $comp, ZLIB_FINISH);
16+
17+
var_dump($out === $data);
18+
?>
19+
--EXPECT--
20+
bool(true)

ext/zlib/zlib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,7 @@ PHP_FUNCTION(inflate_init)
904904
ctx->inflateDictlen = dictlen;
905905
ctx->status = Z_OK;
906906

907+
zend_long orig_encoding = encoding;
907908
if (encoding < 0) {
908909
encoding += 15 - window;
909910
} else {
@@ -917,7 +918,7 @@ PHP_FUNCTION(inflate_init)
917918
RETURN_FALSE;
918919
}
919920

920-
if (encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) {
921+
if (orig_encoding == PHP_ZLIB_ENCODING_RAW && dictlen > 0) {
921922
switch (inflateSetDictionary(&ctx->Z, (Bytef *) ctx->inflateDict, ctx->inflateDictlen)) {
922923
case Z_OK:
923924
efree(ctx->inflateDict);

0 commit comments

Comments
 (0)