[php-src] Issue #12986: `HASH_FLAG_ALLOW_COW_VIOLATION` is not preserved by `zend_hash_real_init_(mixed|packed)_ex()`
| From: | ju1ius | Date: | Wed, 20 Dec 2023 21:33:55 +0000 |
| Subject: | [php-src] Issue #12986: `HASH_FLAG_ALLOW_COW_VIOLATION` is not preserved by `zend_hash_real_init_(mixed|packed)_ex()` | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-246085@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/12986
Author: ju1ius
### Description
Hi,
Currently the
[zend_hash_real_init_mixed_ex](https://heap.space/xref/php-src/Zend/zend_hash.c?r=b175ea42#167) and
[zend_hash_real_init_packed_ex](https://heap.space/xref/php-src/Zend/zend_hash.c?r=b175ea42#149)
functions overwrite the hashtable flags which causes the following example to fail:
```c
// allocate a hashtable
HashTable *ht = (HashTable*) emalloc(sizeof(HashTable));
_zend_hash_init(ht, HT_MIN_SIZE, NULL, false);
// then sometime later:
{
GC_ADDREF(ht);
HT_ALLOW_COW_VIOLATION(ht);
zval *value;
ZVAL_LONG(value, 1);
// HT_ASSERT_RC1(ht) succeeds here because HASH_FLAG_ALLOW_COW_VIOLATION is set.
// However, since the hashtable is uninitialized at this point,
// zend_hash_real_init_packed_ex() is called after the check, which unsets the flag.
zend_hash_next_index_insert(ht, value);
ZVAL_LONG(value, 2);
// HT_ASSERT_RC1(ht) fails here because HASH_FLAG_ALLOW_COW_VIOLATION
// was cleared in the previous step.
zend_hash_next_index_insert(ht, value);
GC_DELREF(ht);
}
```
Would you consider a PR that preserves this flag through the initialization process ?
Thanks.
### PHP Version
PHP 8.3-dev
### Operating System
irrelevant