Skip to content

Commit f8c854e

Browse files
committed
1 parent 7e0d5c7 commit f8c854e

7 files changed

Lines changed: 96 additions & 13 deletions

File tree

ext/zlib/tests/filter_broken_object_options.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,8 @@ stream_filter_append($fp, 'zlib.inflate', STREAM_FILTER_WRITE, new Params);
1717
fwrite($fp, "Hello world, hopefully not broken\n");
1818

1919
?>
20-
--EXPECT--
20+
--EXPECTF--
21+
Deprecated: stream_filter_append(): Passing an object for filter parameters for zlib.deflate is deprecated, call get_object_vars() first instead in %s on line %d
22+
23+
Deprecated: stream_filter_append(): Passing an object for filter parameters for zlib.inflate is deprecated, call get_object_vars() first instead in %s on line %d
2124
Hello world, hopefully not broken

ext/zlib/tests/gh17745.phpt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ class Options {
1313
}
1414
var_dump(deflate_init(ZLIB_ENCODING_RAW, new Options));
1515
?>
16-
--EXPECT--
16+
--EXPECTF--
17+
Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
1718
object(DeflateContext)#2 (0) {
1819
}
20+
21+
Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
1922
object(DeflateContext)#3 (0) {
2023
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
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(inflate_init(ZLIB_ENCODING_RAW, $obj));
10+
11+
class Options {
12+
public int $level = 3;
13+
}
14+
var_dump(inflate_init(ZLIB_ENCODING_RAW, new Options));
15+
?>
16+
--EXPECTF--
17+
Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
18+
object(InflateContext)#2 (0) {
19+
}
20+
21+
Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
22+
object(InflateContext)#3 (0) {
23+
}

ext/zlib/tests/gh22142.phpt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ try {
1616
}
1717

1818
?>
19-
--EXPECT--
19+
--EXPECTF--
20+
Deprecated: deflate_init(): Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
2021
TypeError: deflate_init(): Argument #2 ($options) the value for option "level" must be of type int, null given
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF)
3+
--EXTENSIONS--
4+
zlib
5+
--FILE--
6+
<?php
7+
8+
class Options {
9+
public int $window;
10+
}
11+
12+
try {
13+
inflate_init(ZLIB_ENCODING_DEFLATE, new Options());
14+
} catch (TypeError $e) {
15+
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
16+
}
17+
18+
?>
19+
--EXPECTF--
20+
Deprecated: inflate_init(): Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead in %s on line %d
21+
TypeError: inflate_init(): Argument #2 ($options) the value for option "window" must be of type int, null given

ext/zlib/zlib.c

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -881,12 +881,24 @@ PHP_FUNCTION(inflate_init)
881881
zend_long encoding, window = 15;
882882
char *dict = NULL;
883883
size_t dictlen = 0;
884+
zval *options_zv = NULL;
884885
HashTable *options = (HashTable *) &zend_empty_array;
885886

886-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
887+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|A", &encoding, &options_zv)) {
887888
RETURN_THROWS();
888889
}
889890

891+
if (options_zv) {
892+
if (Z_TYPE_P(options_zv) == IS_OBJECT) {
893+
php_error_docref(NULL, E_DEPRECATED,
894+
"Passing an object for argument #2 $option to inflate_init() is deprecated, call get_object_vars() first instead");
895+
if (UNEXPECTED(EG(exception))) {
896+
RETURN_THROWS();
897+
}
898+
}
899+
options = HASH_OF(options_zv);
900+
}
901+
890902
if (!zlib_get_long_option(options, ZEND_STRL("window"), &window)) {
891903
RETURN_THROWS();
892904
}
@@ -1100,12 +1112,24 @@ PHP_FUNCTION(deflate_init)
11001112
zend_long encoding, level = -1, memory = 8, window = 15, strategy = Z_DEFAULT_STRATEGY;
11011113
char *dict = NULL;
11021114
size_t dictlen = 0;
1115+
zval *options_zv = NULL;
11031116
HashTable *options = (HashTable*)&zend_empty_array;
11041117

1105-
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|H", &encoding, &options)) {
1118+
if (SUCCESS != zend_parse_parameters(ZEND_NUM_ARGS(), "l|A", &encoding, &options_zv)) {
11061119
RETURN_THROWS();
11071120
}
11081121

1122+
if (options_zv) {
1123+
if (Z_TYPE_P(options_zv) == IS_OBJECT) {
1124+
php_error_docref(NULL, E_DEPRECATED,
1125+
"Passing an object for argument #2 $option to deflate_init() is deprecated, call get_object_vars() first instead");
1126+
if (UNEXPECTED(EG(exception))) {
1127+
RETURN_THROWS();
1128+
}
1129+
}
1130+
options = HASH_OF(options_zv);
1131+
}
1132+
11091133
if (!zlib_get_long_option(options, ZEND_STRL("level"), &level)) {
11101134
RETURN_THROWS();
11111135
}

ext/zlib/zlib_filter.c

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,22 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
361361
php_zlib_filter_data *data;
362362
int status;
363363

364+
if (filterparams && Z_TYPE_P(filterparams) == IS_OBJECT) {
365+
php_error_docref("filters.compression", E_DEPRECATED,
366+
"Passing an object for filter parameters for %s is deprecated, call get_object_vars() first instead", filtername);
367+
if (UNEXPECTED(EG(exception))) {
368+
return NULL;
369+
}
370+
}
371+
364372
if (php_stream_filter_parse_write_seek_mode(filterparams, &write_seekable) == FAILURE) {
365373
return NULL;
366374
}
367375

368376
/* Create this filter */
369377
data = pecalloc(1, sizeof(php_zlib_filter_data), persistent);
370378
if (!data) {
371-
php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", sizeof(php_zlib_filter_data));
379+
php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", sizeof(php_zlib_filter_data));
372380
return NULL;
373381
}
374382

@@ -380,14 +388,14 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
380388
data->strm.avail_out = data->outbuf_len = data->inbuf_len = 0x8000;
381389
data->strm.next_in = data->inbuf = (Bytef *) pemalloc(data->inbuf_len, persistent);
382390
if (!data->inbuf) {
383-
php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", data->inbuf_len);
391+
php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", data->inbuf_len);
384392
pefree(data, persistent);
385393
return NULL;
386394
}
387395
data->strm.avail_in = 0;
388396
data->strm.next_out = data->outbuf = (Bytef *) pemalloc(data->outbuf_len, persistent);
389397
if (!data->outbuf) {
390-
php_error_docref(NULL, E_WARNING, "Failed allocating %zd bytes", data->outbuf_len);
398+
php_error_docref("filters.compression", E_WARNING, "Failed allocating %zd bytes", data->outbuf_len);
391399
pefree(data->inbuf, persistent);
392400
pefree(data, persistent);
393401
return NULL;
@@ -407,7 +415,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
407415
/* log-2 base of history window (9 - 15) */
408416
zend_long tmp = zval_get_long(tmpzval);
409417
if (tmp < -MAX_WBITS || tmp > MAX_WBITS + 32) {
410-
php_error_docref(NULL, E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp);
418+
php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp);
411419
} else {
412420
windowBits = tmp;
413421
}
@@ -444,7 +452,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
444452
/* Memory Level (1 - 9) */
445453
tmp = zval_get_long(tmpzval);
446454
if (tmp < 1 || tmp > MAX_MEM_LEVEL) {
447-
php_error_docref(NULL, E_WARNING, "Invalid parameter given for memory level (" ZEND_LONG_FMT ")", tmp);
455+
php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for memory level (" ZEND_LONG_FMT ")", tmp);
448456
} else {
449457
memLevel = tmp;
450458
}
@@ -454,7 +462,7 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
454462
/* log-2 base of history window (9 - 15) */
455463
tmp = zval_get_long(tmpzval);
456464
if (tmp < -MAX_WBITS || tmp > MAX_WBITS + 16) {
457-
php_error_docref(NULL, E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp);
465+
php_error_docref("filters.compression", E_WARNING, "Invalid parameter given for window size (" ZEND_LONG_FMT ")", tmp);
458466
} else {
459467
windowBits = tmp;
460468
}
@@ -475,13 +483,13 @@ static php_stream_filter *php_zlib_filter_create(const char *filtername, zval *f
475483
factory_setlevel:
476484
/* Set compression level within reason (-1 == default, 0 == none, 1-9 == least to most compression */
477485
if (tmp < -1 || tmp > 9) {
478-
php_error_docref(NULL, E_WARNING, "Invalid compression level specified. (" ZEND_LONG_FMT ")", tmp);
486+
php_error_docref("filters.compression", E_WARNING, "Invalid compression level specified. (" ZEND_LONG_FMT ")", tmp);
479487
} else {
480488
level = tmp;
481489
}
482490
break;
483491
default:
484-
php_error_docref(NULL, E_WARNING, "Invalid filter parameter, ignored");
492+
php_error_docref("filters.compression", E_WARNING, "Invalid filter parameter, ignored");
485493
}
486494
}
487495

0 commit comments

Comments
 (0)