Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions ext/zlib/tests/gh22142.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
GH-22142 (Assertion failure in zendi_try_get_long() on IS_UNDEF)
--CREDITS--
JIANG Yuancheng
--EXTENSIONS--
zlib
--INI--
error_reporting=E_ALL & ~E_DEPRECATED
--FILE--
<?php

class DeflateOptions {
public int $level;
public int $memory;
public int $window;
public int $strategy;
public string $dictionary;
}

class InflateOptions {
public int $window;
public string $dictionary;
}

class BadDeflateOptions {
public int $level = 42;
public int $memory;
}

$deflate = new DeflateOptions();
var_dump(deflate_init(ZLIB_ENCODING_DEFLATE, $deflate) instanceof DeflateContext);
var_dump(deflate_init(ZLIB_ENCODING_DEFLATE, get_object_vars($deflate)) instanceof DeflateContext);

$inflate = new InflateOptions();
var_dump(inflate_init(ZLIB_ENCODING_DEFLATE, $inflate) instanceof InflateContext);
var_dump(inflate_init(ZLIB_ENCODING_DEFLATE, get_object_vars($inflate)) instanceof InflateContext);

try {
deflate_init(ZLIB_ENCODING_DEFLATE, new BadDeflateOptions());
} catch (ValueError $e) {
echo $e::class, ': ', $e->getMessage(), PHP_EOL;
}

?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
ValueError: deflate_init(): "level" option must be between -1 and 9
21 changes: 0 additions & 21 deletions ext/zlib/tests/gh22142_inflate.phpt

This file was deleted.

23 changes: 18 additions & 5 deletions ext/zlib/zlib.c
Original file line number Diff line number Diff line change
Expand Up @@ -779,11 +779,26 @@ PHP_ZLIB_DECODE_FUNC(gzdecode, PHP_ZLIB_ENCODING_GZIP);
PHP_ZLIB_DECODE_FUNC(gzuncompress, PHP_ZLIB_ENCODING_DEFLATE);
/* }}} */

ZEND_ATTRIBUTE_NONNULL static zval *zlib_find_option(HashTable *options, const char *name, size_t name_len)
{
zval *option = zend_hash_str_find(options, name, name_len);

if (!option) {
return NULL;
}

ZVAL_DEINDIRECT(option);

if (UNEXPECTED(Z_TYPE_P(option) == IS_UNDEF)) {
return NULL;
}
return option;
}

static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_t *dictlen) {
zval *option_buffer;

if (options && (option_buffer = zend_hash_str_find(options, ZEND_STRL("dictionary"))) != NULL) {
ZVAL_DEINDIRECT(option_buffer);
if (options && (option_buffer = zlib_find_option(options, ZEND_STRL("dictionary"))) != NULL) {
ZVAL_DEREF(option_buffer);
switch (Z_TYPE_P(option_buffer)) {
case IS_STRING: {
Expand Down Expand Up @@ -853,14 +868,12 @@ static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_
ZEND_ATTRIBUTE_NONNULL static bool zlib_get_long_option(HashTable *options, const char *option_name, size_t option_name_len, zend_long *value)
{
bool failed = false;
zval *option_buffer = zend_hash_str_find(options, option_name, option_name_len);
zval *option_buffer = zlib_find_option(options, option_name, option_name_len);

if (!option_buffer) {
return true;
}

/* The |H ZPP specifier may leave HashTable entries wrapped in IS_INDIRECT. */
ZVAL_DEINDIRECT(option_buffer);
*value = zval_try_get_long(option_buffer, &failed);
if (UNEXPECTED(failed)) {
zend_argument_type_error(
Expand Down
Loading