mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Merge branch 'PHP-8.2'
This commit is contained in:
commit
a9d11b64a7
3 changed files with 68 additions and 7 deletions
29
Zend/tests/gh11189.phpt
Normal file
29
Zend/tests/gh11189.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
GH-11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state (packed array)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (getenv("USE_ZEND_ALLOC") === "0") die("skip ZMM is disabled");
|
||||||
|
?>
|
||||||
|
--INI--
|
||||||
|
memory_limit=2M
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
ob_start(function() {
|
||||||
|
global $a;
|
||||||
|
for ($i = count($a); $i > 0; --$i) {
|
||||||
|
$a[] = 2;
|
||||||
|
}
|
||||||
|
fwrite(STDOUT, "Success");
|
||||||
|
});
|
||||||
|
|
||||||
|
$a = [];
|
||||||
|
// trigger OOM in a resize operation
|
||||||
|
while (1) {
|
||||||
|
$a[] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Success
|
||||||
|
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
|
29
Zend/tests/gh11189_1.phpt
Normal file
29
Zend/tests/gh11189_1.phpt
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
--TEST--
|
||||||
|
GH-11189: Exceeding memory limit in zend_hash_do_resize leaves the array in an invalid state (not packed array)
|
||||||
|
--SKIPIF--
|
||||||
|
<?php
|
||||||
|
if (getenv("USE_ZEND_ALLOC") === "0") die("skip ZMM is disabled");
|
||||||
|
?>
|
||||||
|
--INI--
|
||||||
|
memory_limit=2M
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
ob_start(function() {
|
||||||
|
global $a;
|
||||||
|
for ($i = count($a); $i > 0; --$i) {
|
||||||
|
$a[] = 2;
|
||||||
|
}
|
||||||
|
fwrite(STDOUT, "Success");
|
||||||
|
});
|
||||||
|
|
||||||
|
$a = ["not packed" => 1];
|
||||||
|
// trigger OOM in a resize operation
|
||||||
|
while (1) {
|
||||||
|
$a[] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
||||||
|
--EXPECTF--
|
||||||
|
Success
|
||||||
|
Fatal error: Allowed memory size of %s bytes exhausted%s(tried to allocate %s bytes) in %s on line %d
|
|
@ -314,8 +314,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_grow(HashTable *ht)
|
||||||
if (ht->nTableSize >= HT_MAX_SIZE) {
|
if (ht->nTableSize >= HT_MAX_SIZE) {
|
||||||
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
zend_error_noreturn(E_ERROR, "Possible integer overflow in memory allocation (%u * %zu + %zu)", ht->nTableSize * 2, sizeof(Bucket), sizeof(Bucket));
|
||||||
}
|
}
|
||||||
ht->nTableSize += ht->nTableSize;
|
uint32_t newTableSize = ht->nTableSize * 2;
|
||||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_PACKED_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_PACKED_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_PACKED_SIZE_EX(newTableSize, HT_MIN_MASK), HT_PACKED_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
||||||
|
ht->nTableSize = newTableSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, bool packed)
|
ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, bool packed)
|
||||||
|
@ -353,8 +354,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_packed_to_hash(HashTable *ht)
|
||||||
ZEND_ASSERT(HT_SIZE_TO_MASK(nSize));
|
ZEND_ASSERT(HT_SIZE_TO_MASK(nSize));
|
||||||
|
|
||||||
HT_ASSERT_RC1(ht);
|
HT_ASSERT_RC1(ht);
|
||||||
HT_FLAGS(ht) &= ~HASH_FLAG_PACKED;
|
// Alloc before assign to avoid inconsistencies on OOM
|
||||||
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||||
|
HT_FLAGS(ht) &= ~HASH_FLAG_PACKED;
|
||||||
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
||||||
HT_SET_DATA_ADDR(ht, new_data);
|
HT_SET_DATA_ADDR(ht, new_data);
|
||||||
dst = ht->arData;
|
dst = ht->arData;
|
||||||
|
@ -408,8 +410,9 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool
|
||||||
if (packed) {
|
if (packed) {
|
||||||
ZEND_ASSERT(HT_IS_PACKED(ht));
|
ZEND_ASSERT(HT_IS_PACKED(ht));
|
||||||
if (nSize > ht->nTableSize) {
|
if (nSize > ht->nTableSize) {
|
||||||
ht->nTableSize = zend_hash_check_size(nSize);
|
uint32_t newTableSize = zend_hash_check_size(nSize);
|
||||||
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_PACKED_SIZE_EX(ht->nTableSize, HT_MIN_MASK), HT_PACKED_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
HT_SET_DATA_ADDR(ht, perealloc2(HT_GET_DATA_ADDR(ht), HT_PACKED_SIZE_EX(newTableSize, HT_MIN_MASK), HT_PACKED_USED_SIZE(ht), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT));
|
||||||
|
ht->nTableSize = newTableSize;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ZEND_ASSERT(!HT_IS_PACKED(ht));
|
ZEND_ASSERT(!HT_IS_PACKED(ht));
|
||||||
|
@ -417,8 +420,8 @@ ZEND_API void ZEND_FASTCALL zend_hash_extend(HashTable *ht, uint32_t nSize, bool
|
||||||
void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
|
void *new_data, *old_data = HT_GET_DATA_ADDR(ht);
|
||||||
Bucket *old_buckets = ht->arData;
|
Bucket *old_buckets = ht->arData;
|
||||||
nSize = zend_hash_check_size(nSize);
|
nSize = zend_hash_check_size(nSize);
|
||||||
ht->nTableSize = nSize;
|
|
||||||
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||||
|
ht->nTableSize = nSize;
|
||||||
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
||||||
HT_SET_DATA_ADDR(ht, new_data);
|
HT_SET_DATA_ADDR(ht, new_data);
|
||||||
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
|
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
|
||||||
|
@ -1247,8 +1250,8 @@ static void ZEND_FASTCALL zend_hash_do_resize(HashTable *ht)
|
||||||
|
|
||||||
ZEND_ASSERT(HT_SIZE_TO_MASK(nSize));
|
ZEND_ASSERT(HT_SIZE_TO_MASK(nSize));
|
||||||
|
|
||||||
ht->nTableSize = nSize;
|
|
||||||
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
new_data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
|
||||||
|
ht->nTableSize = nSize;
|
||||||
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
ht->nTableMask = HT_SIZE_TO_MASK(ht->nTableSize);
|
||||||
HT_SET_DATA_ADDR(ht, new_data);
|
HT_SET_DATA_ADDR(ht, new_data);
|
||||||
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
|
memcpy(ht->arData, old_buckets, sizeof(Bucket) * ht->nNumUsed);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue