1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Merge branch 'PHP-8.4'

* PHP-8.4:
  Fix GH-16326: Memory management is broken for bad dictionaries
This commit is contained in:
Christoph M. Becker
2024-10-13 02:31:16 +02:00
2 changed files with 39 additions and 19 deletions

View File

@@ -0,0 +1,26 @@
--TEST--
GH-16326 (Memory management is broken for bad dictionaries)
--EXTENSIONS--
zlib
--FILE--
<?php
try {
deflate_init(ZLIB_ENCODING_DEFLATE, ["dictionary" => [" ", ""]]);
} catch (ValueError $ex) {
echo $ex->getMessage(), "\n";
}
try {
deflate_init(ZLIB_ENCODING_DEFLATE, ["dictionary" => ["hello", "wor\0ld"]]);
} catch (ValueError $ex) {
echo $ex->getMessage(), "\n";
}
try {
deflate_init(ZLIB_ENCODING_DEFLATE, ["dictionary" => [" ", new stdClass]]);
} catch (Error $ex) {
echo $ex->getMessage(), "\n";
}
?>
--EXPECT--
deflate_init(): Argument #2 ($options) must not contain empty strings
deflate_init(): Argument #2 ($options) must not contain strings with null bytes
Object of class stdClass could not be converted to string

View File

@@ -804,35 +804,29 @@ static bool zlib_create_dictionary_string(HashTable *options, char **dict, size_
if (zend_hash_num_elements(dictionary) > 0) {
char *dictptr;
zval *cur;
zend_string **strings = emalloc(sizeof(zend_string *) * zend_hash_num_elements(dictionary));
zend_string **strings = safe_emalloc(zend_hash_num_elements(dictionary), sizeof(zend_string *), 0);
zend_string **end, **ptr = strings - 1;
ZEND_HASH_FOREACH_VAL(dictionary, cur) {
size_t i;
*++ptr = zval_get_string(cur);
if (!*ptr || ZSTR_LEN(*ptr) == 0 || EG(exception)) {
if (*ptr) {
efree(*ptr);
}
while (--ptr >= strings) {
efree(ptr);
}
ZEND_ASSERT(*ptr);
if (ZSTR_LEN(*ptr) == 0 || EG(exception)) {
do {
zend_string_release(*ptr);
} while (--ptr >= strings);
efree(strings);
if (!EG(exception)) {
zend_argument_value_error(2, "must not contain empty strings");
}
return 0;
}
for (i = 0; i < ZSTR_LEN(*ptr); i++) {
if (ZSTR_VAL(*ptr)[i] == 0) {
do {
efree(ptr);
} while (--ptr >= strings);
efree(strings);
zend_argument_value_error(2, "must not contain strings with null bytes");
return 0;
}
if (zend_str_has_nul_byte(*ptr)) {
do {
zend_string_release(*ptr);
} while (--ptr >= strings);
efree(strings);
zend_argument_value_error(2, "must not contain strings with null bytes");
return 0;
}
*dictlen += ZSTR_LEN(*ptr) + 1;