diff options
author | Xinchen Hui <laruence@gmail.com> | 2015-11-23 06:12:03 -0800 |
---|---|---|
committer | Xinchen Hui <laruence@gmail.com> | 2015-11-23 06:12:03 -0800 |
commit | 6313e16a0472d42a2056364b1aacd7798d500b75 (patch) | |
tree | 75b8462f49a2ffaabf3d6458f2246392d3ac59bb /Zend/zend_hash.c | |
parent | 8c51578c81c04b6e9efa03b75e9473cfa5ad550f (diff) | |
download | php-git-6313e16a0472d42a2056364b1aacd7798d500b75.tar.gz |
Improved fix for bug (count on symbol table)
Diffstat (limited to 'Zend/zend_hash.c')
-rw-r--r-- | Zend/zend_hash.c | 36 |
1 files changed, 36 insertions, 0 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index c324f1dfa8..283ceb8c18 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -283,6 +283,40 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, zend } } +static uint32_t zend_array_recalc_elements(HashTable *ht) +{ + zval *val; + uint32_t num = ht->nNumOfElements; + + ZEND_HASH_FOREACH_VAL(ht, val) { + if (Z_TYPE_P(val) == IS_UNDEF) continue; + if (Z_TYPE_P(val) == IS_INDIRECT) { + if (UNEXPECTED(Z_TYPE_P(Z_INDIRECT_P(val)) == IS_UNDEF)) { + num--; + } + } + } ZEND_HASH_FOREACH_END(); + return num; +} +/* }}} */ + +ZEND_API uint32_t zend_array_count(HashTable *ht) +{ + uint32_t num; + if (UNEXPECTED(ht->u.v.flags & HASH_FLAG_HAS_EMPTY_IND)) { + num = zend_array_recalc_elements(ht); + if (UNEXPECTED(ht->nNumOfElements == num)) { + ht->u.v.flags &= ~HASH_FLAG_HAS_EMPTY_IND; + } + } else if (UNEXPECTED(ht == &EG(symbol_table))) { + num = zend_array_recalc_elements(ht); + } else { + num = zend_hash_num_elements(ht); + } + return num; +} +/* }}} */ + ZEND_API void ZEND_FASTCALL zend_hash_set_apply_protection(HashTable *ht, zend_bool bApplyProtection) { if (bApplyProtection) { @@ -1056,6 +1090,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_del_ind(HashTable *ht, zend_string *key) } else { ZVAL_UNDEF(data); } + ht->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; } } else { _zend_hash_del_el_ex(ht, idx, p, prev); @@ -1099,6 +1134,7 @@ ZEND_API int ZEND_FASTCALL zend_hash_str_del_ind(HashTable *ht, const char *str, ht->pDestructor(data); } ZVAL_UNDEF(data); + ht->u.v.flags |= HASH_FLAG_HAS_EMPTY_IND; } } else { _zend_hash_del_el_ex(ht, idx, p, prev); |