summaryrefslogtreecommitdiff
path: root/Zend/zend_hash.c
diff options
context:
space:
mode:
authorXinchen Hui <laruence@php.net>2015-08-10 17:02:16 +0800
committerXinchen Hui <laruence@php.net>2015-08-10 17:02:16 +0800
commitbe54eb7db10c6aa838cef969822a5ae0f4e605e3 (patch)
treeafbab0211d22de8ed5500bded850f2a5086276f0 /Zend/zend_hash.c
parent7600f5246c8f5465f0c457c238cafac9897c1128 (diff)
downloadphp-git-be54eb7db10c6aa838cef969822a5ae0f4e605e3.tar.gz
Fixed bug #70211 (php 7 ZEND_HASH_IF_FULL_DO_RESIZE use after free)
Diffstat (limited to 'Zend/zend_hash.c')
-rw-r--r--Zend/zend_hash.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c
index eb5081d56c..0d3932ebd4 100644
--- a/Zend/zend_hash.c
+++ b/Zend/zend_hash.c
@@ -807,6 +807,20 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
}
}
+ZEND_API int ZEND_FASTCALL zend_hash_resize(HashTable *ht, uint32_t size) {
+ void *old_data = HT_GET_DATA_ADDR(ht);
+ Bucket *old_buckets = ht->arData;
+
+ HANDLE_BLOCK_INTERRUPTIONS();
+ ht->nTableSize = zend_hash_check_size(size);
+ ht->nTableMask = -ht->nTableSize;
+ HT_SET_DATA_ADDR(ht, pemalloc(HT_SIZE(ht), ht->u.flags & HASH_FLAG_PERSISTENT));
+ memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
+ pefree(old_data, ht->u.flags & HASH_FLAG_PERSISTENT);
+ zend_hash_rehash(ht);
+ HANDLE_UNBLOCK_INTERRUPTIONS();
+}
+
ZEND_API int ZEND_FASTCALL zend_hash_rehash(HashTable *ht)
{
Bucket *p;