Skip to content

Commit bc585cd

Browse files
authored
Fix phpGH-14643 ext/standard: segfault on user shutdown function release. (php#14656)
1 parent 4f450b6 commit bc585cd

File tree

2 files changed

+30
-7
lines changed

2 files changed

+30
-7
lines changed

Zend/zend_hash.h

+8-7
Original file line numberDiff line numberDiff line change
@@ -851,15 +851,16 @@ static zend_always_inline void *zend_hash_index_update_mem(HashTable *ht, zend_u
851851

852852
static zend_always_inline void *zend_hash_next_index_insert_mem(HashTable *ht, void *pData, size_t size)
853853
{
854-
zval tmp, *zv;
854+
zval tmp;
855855

856-
ZVAL_PTR(&tmp, NULL);
857-
if ((zv = zend_hash_next_index_insert(ht, &tmp))) {
858-
Z_PTR_P(zv) = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
859-
memcpy(Z_PTR_P(zv), pData, size);
860-
return Z_PTR_P(zv);
856+
void *p = pemalloc(size, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
857+
memcpy(p, pData, size);
858+
ZVAL_PTR(&tmp, p);
859+
if (!zend_hash_next_index_insert(ht, &tmp)) {
860+
pefree(p, GC_FLAGS(ht) & IS_ARRAY_PERSISTENT);
861+
return NULL;
861862
}
862-
return NULL;
863+
return p;
863864
}
864865

865866
static zend_always_inline void *zend_hash_find_ptr(const HashTable *ht, zend_string *key)
+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
GH-14643: Segfault on empty user function.
3+
--FILE--
4+
<?php
5+
class Logger {
6+
public function __construct() {
7+
register_shutdown_function(function () {
8+
$this->flush();
9+
register_shutdown_function([$this, 'flush'], true);
10+
});
11+
}
12+
public function flush($final = false) {
13+
}
14+
}
15+
while (true) {
16+
$a = new Logger();
17+
}
18+
?>
19+
--EXPECTF--
20+
Fatal error: Allowed memory size of %d bytes exhausted %s
21+
22+
Fatal error: Allowed memory size of %d bytes exhausted %s

0 commit comments

Comments
 (0)