mirror of
https://github.com/php/php-src.git
synced 2024-11-27 03:44:07 +08:00
Replace ZEND_ASSUME()
by ZEND_ASSERT()
in zend_hash_*_ptr
setters (#14466)
I had a case where I was intentionally storing a `NULL` pointer within a HashTable to mark an entry as “blocked”, without paying for the overhead of checking the entry type when reading the pointer, resulting in semantics that are similar to using `isset()` instead of `array_key_exists()` in userland. This worked fine in unoptimized test builds, but due to the `ZEND_ASSUME()` in the `zend_hash_find_ptr` functions, the optimized release builds turned the logic of: my_pointer = zend_hash_find_ptr(ht, key); if (my_pointer == NULL) { return; } *my_pointer; into zv = zend_hash_find(ht, key); if (zv) { *Z_PTR_P(zv); } else { return; } thus introducing a hard-to-debug and compiler-dependent crash when the entry exists, but the stored pointer is `NULL`. Change the `ZEND_ASSUME()` in the setters to `ZEND_ASSERT()`. This would have made my mistake immediately obvious in debug builds when storing the pointer. The getters still use `ZEND_ASSUME()` under the assumption that they are called much more often, reducing the impact on debug builds: Assuming the developer uses the `_ptr` variants for both reading and writing the entries, the mistake will be reliably caught during writing, making the assert during reading unnecessary. For release builds the `ZEND_ASSERT()` will be equivalent to `ZEND_ASSUME()`, avoiding any performance impact for those.
This commit is contained in:
parent
bda372fc6c
commit
7c2a4dbd72
@ -646,7 +646,7 @@ static zend_always_inline void *zend_hash_add_ptr(HashTable *ht, zend_string *ke
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_add(ht, key, &tmp);
|
||||
if (zv) {
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
} else {
|
||||
return NULL;
|
||||
@ -660,7 +660,7 @@ static zend_always_inline void *zend_hash_add_new_ptr(HashTable *ht, zend_string
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_add_new(ht, key, &tmp);
|
||||
if (zv) {
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
} else {
|
||||
return NULL;
|
||||
@ -674,7 +674,7 @@ static zend_always_inline void *zend_hash_str_add_ptr(HashTable *ht, const char
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_str_add(ht, str, len, &tmp);
|
||||
if (zv) {
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
} else {
|
||||
return NULL;
|
||||
@ -688,7 +688,7 @@ static zend_always_inline void *zend_hash_str_add_new_ptr(HashTable *ht, const c
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_str_add_new(ht, str, len, &tmp);
|
||||
if (zv) {
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
} else {
|
||||
return NULL;
|
||||
@ -701,7 +701,7 @@ static zend_always_inline void *zend_hash_update_ptr(HashTable *ht, zend_string
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_update(ht, key, &tmp);
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
|
||||
@ -711,7 +711,7 @@ static zend_always_inline void *zend_hash_str_update_ptr(HashTable *ht, const ch
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_str_update(ht, str, len, &tmp);
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
|
||||
@ -809,7 +809,7 @@ static zend_always_inline void *zend_hash_index_update_ptr(HashTable *ht, zend_u
|
||||
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_index_update(ht, h, &tmp);
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
}
|
||||
|
||||
@ -833,7 +833,7 @@ static zend_always_inline void *zend_hash_next_index_insert_ptr(HashTable *ht, v
|
||||
ZVAL_PTR(&tmp, pData);
|
||||
zv = zend_hash_next_index_insert(ht, &tmp);
|
||||
if (zv) {
|
||||
ZEND_ASSUME(Z_PTR_P(zv));
|
||||
ZEND_ASSERT(Z_PTR_P(zv));
|
||||
return Z_PTR_P(zv);
|
||||
} else {
|
||||
return NULL;
|
||||
|
Loading…
Reference in New Issue
Block a user