Commit c23efeb5c4b for php.net
commit c23efeb5c4b35990d604ed659f13ea5edd238e6d
Author: Weilin Du <108666168+LamentXU123@users.noreply.github.com>
Date: Fri Apr 24 00:35:49 2026 +0800
Zlib: Fix the bug when `zval_get_long` silently cast `$strategy` into long in `deflate_init` (#21841)
diff --git a/NEWS b/NEWS
index 18d12d02dbb..d2614887767 100644
--- a/NEWS
+++ b/NEWS
@@ -197,4 +197,8 @@ PHP NEWS
. Added ZipArchive::openString() method.
(Tim Starling, Soner Sayakci, Ghaith Olabi)
+- Zlib:
+ . deflate_init() now raises a TypeError when the value for option
+ "strategy" is not of type int. (Weilin Du)
+
<<< NOTE: Insert NEWS from last stable release here prior to actual release! >>>
diff --git a/UPGRADING b/UPGRADING
index f24ea681be2..6c6115ebcc8 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -101,6 +101,10 @@ PHP 8.6 UPGRADE NOTES
files argument if one or more of the entries is not
a string.
+- Zlib:
+ . deflate_init() now raises a TypeError when the value for option
+ "strategy" is not of type int.
+
========================================
2. New Features
========================================
diff --git a/ext/zlib/tests/deflate_init_strategy_type_error.phpt b/ext/zlib/tests/deflate_init_strategy_type_error.phpt
new file mode 100644
index 00000000000..0227d1bf6c2
--- /dev/null
+++ b/ext/zlib/tests/deflate_init_strategy_type_error.phpt
@@ -0,0 +1,16 @@
+--TEST--
+deflate_init(): strategy option type validation
+--EXTENSIONS--
+zlib
+--FILE--
+<?php
+
+try {
+ deflate_init(ZLIB_ENCODING_DEFLATE, ['strategy' => []]);
+} catch (TypeError $e) {
+ echo $e->getMessage(), PHP_EOL;
+}
+
+?>
+--EXPECT--
+deflate_init(): Argument #2 ($options) the value for option "strategy" must be of type int, array given
diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c
index dbbaf1a2415..115eedbc894 100644
--- a/ext/zlib/zlib.c
+++ b/ext/zlib/zlib.c
@@ -1115,8 +1115,14 @@ PHP_FUNCTION(deflate_init)
}
if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("strategy"))) != NULL) {
+ bool failed = false;
+
ZVAL_DEINDIRECT(option_buffer);
- strategy = zval_get_long(option_buffer);
+ strategy = zval_try_get_long(option_buffer, &failed);
+ if (UNEXPECTED(failed)) {
+ zend_argument_type_error(2, "the value for option \"strategy\" must be of type int, %s given", zend_zval_value_name(option_buffer));
+ RETURN_THROWS();
+ }
}
switch (strategy) {
case Z_FILTERED: