diff --git a/ext/zlib/tests/gh22142.phpt b/ext/zlib/tests/gh22142.phpt new file mode 100644 index 000000000000..8632146dade6 --- /dev/null +++ b/ext/zlib/tests/gh22142.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-22142: deflate_init() handles undefined variable without assertion failure +--FILE-- +getMessage(), "\n"; +} + +?> +--EXPECTF-- +Warning: Undefined variable $fusion in %s on line %d + +Deprecated: deflate_init(): Passing null to parameter #1 ($encoding) of type int is deprecated in %s on line %d +TypeError: deflate_init(): Argument #2 ($options) the value for option "level" must be of type int, null given diff --git a/ext/zlib/zlib.c b/ext/zlib/zlib.c index 3b987fa45e48..59672e5dd918 100644 --- a/ext/zlib/zlib.c +++ b/ext/zlib/zlib.c @@ -865,6 +865,17 @@ ZEND_ATTRIBUTE_NONNULL static bool zlib_get_long_option(HashTable *options, cons /* The |H ZPP specifier may leave HashTable entries wrapped in IS_INDIRECT. */ ZVAL_DEINDIRECT(option_buffer); + if (UNEXPECTED(Z_TYPE_P(option_buffer) == IS_UNDEF)) { + zend_argument_type_error( + 2, + "the value for option \"%.*s\" must be of type int, %s given", + (int) option_name_len, + option_name, + zend_zval_value_name(option_buffer) + ); + return false; + } + *value = zval_try_get_long(option_buffer, &failed); if (UNEXPECTED(failed)) { zend_argument_type_error(