Skip to content

Commit 4b5c29e

Browse files
committed
Fix GH-17745: zlib extension incorrectly handles object arguments
Because of the "H" modifier in ZPP, there are two bugs: 1) The stub is wrong and will cause a crash in debug mode. 2) Non-dynamic properties are not read correctly because they are not DEINDIRECTed. Closes GH-17750.
1 parent 6ea1c7c commit 4b5c29e

File tree

5 files changed

+35
-5
lines changed

5 files changed

+35
-5
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ PHP NEWS
3838
- Streams:
3939
. Fixed bug GH-17650 (realloc with size 0 in user_filters.c). (nielsdos)
4040

41+
- Zlib:
42+
. Fixed bug GH-17745 (zlib extension incorrectly handles object arguments).
43+
(nielsdos)
44+
4145
13 Feb 2025, PHP 8.3.17
4246

4347
- Core:

ext/zlib/tests/gh17745.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
GH-17745 (zlib extension incorrectly handles object arguments)
3+
--EXTENSIONS--
4+
zlib
5+
--FILE--
6+
<?php
7+
$obj = new stdClass;
8+
$obj->level = 3;
9+
var_dump(deflate_init(ZLIB_ENCODING_RAW, $obj));
10+
11+
class Options {
12+
public int $level = 3;
13+
}
14+
var_dump(deflate_init(ZLIB_ENCODING_RAW, new Options));
15+
?>
16+
--EXPECT--
17+
object(DeflateContext)#2 (0) {
18+
}
19+
object(DeflateContext)#3 (0) {
20+
}

ext/zlib/zlib.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,7 @@ static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_
790790
zval *option_buffer;
791791

792792
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) {
793+
ZVAL_DEINDIRECT(option_buffer);
793794
ZVAL_DEREF(option_buffer);
794795
switch (Z_TYPE_P(option_buffer)) {
795796
case IS_STRING: {
@@ -870,6 +871,7 @@ PHP_FUNCTION(inflate_init)
870871
}
871872

872873
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
874+
ZVAL_DEINDIRECT(option_buffer);
873875
window = zval_get_long(option_buffer);
874876
}
875877
if (window < 8 || window > 15) {
@@ -1088,6 +1090,7 @@ PHP_FUNCTION(deflate_init)
10881090
}
10891091

10901092
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("level"))) != NULL) {
1093+
ZVAL_DEINDIRECT(option_buffer);
10911094
level = zval_get_long(option_buffer);
10921095
}
10931096
if (level < -1 || level > 9) {
@@ -1096,6 +1099,7 @@ PHP_FUNCTION(deflate_init)
10961099
}
10971100

10981101
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("memory"))) != NULL) {
1102+
ZVAL_DEINDIRECT(option_buffer);
10991103
memory = zval_get_long(option_buffer);
11001104
}
11011105
if (memory < 1 || memory > 9) {
@@ -1104,6 +1108,7 @@ PHP_FUNCTION(deflate_init)
11041108
}
11051109

11061110
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("window"))) != NULL) {
1111+
ZVAL_DEINDIRECT(option_buffer);
11071112
window = zval_get_long(option_buffer);
11081113
}
11091114
if (window < 8 || window > 15) {
@@ -1112,6 +1117,7 @@ PHP_FUNCTION(deflate_init)
11121117
}
11131118

11141119
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("strategy"))) != NULL) {
1120+
ZVAL_DEINDIRECT(option_buffer);
11151121
strategy = zval_get_long(option_buffer);
11161122
}
11171123
switch (strategy) {

ext/zlib/zlib.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,11 +270,11 @@ function gzread($stream, int $length): string|false {}
270270
*/
271271
function gzgets($stream, ?int $length = null): string|false {}
272272

273-
function deflate_init(int $encoding, array $options = []): DeflateContext|false {}
273+
function deflate_init(int $encoding, array|object $options = []): DeflateContext|false {}
274274

275275
function deflate_add(DeflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false {}
276276

277-
function inflate_init(int $encoding, array $options = []): InflateContext|false {}
277+
function inflate_init(int $encoding, array|object $options = []): InflateContext|false {}
278278

279279
function inflate_add(InflateContext $context, string $data, int $flush_mode = ZLIB_SYNC_FLUSH): string|false {}
280280

ext/zlib/zlib_arginfo.h

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)