1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00
Objects reuse the GC_PERSISTENT flag as IS_OBJ_WEAKLY_REFERENCED,
which we did not account for in ZVAL_COPY_OR_DUP. To make things
worse the incorrect zval_copy_ctor_func() invocation silently did
nothing. To avoid that, add an assertion that it should only be
called with arrays and strings (unlike the normal zval_copy_ctor()
which can be safely called on any zval).
This commit is contained in:
Nikita Popov
2021-10-08 10:31:24 +02:00
parent c9fb384c40
commit bd3e536383
4 changed files with 25 additions and 1 deletions

2
NEWS
View File

@@ -9,6 +9,8 @@ PHP NEWS
. Fixed bug #75941 (Fix compile failure on Solaris with clang). (Jaromír
Doleček)
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
. Fixed bug #81514 (Using Enum as key in WeakMap triggers GC + SegFault).
(Nikita)
- Date:
. Fixed bug #81504 (Incorrect timezone transition details for POSIX data).

View File

@@ -0,0 +1,18 @@
--TEST--
Use enum as WeakMap key
--FILE--
<?php
enum TestEnum {
case A;
}
$map = new WeakMap();
$map[TestEnum::A] = 'a string';
var_dump($map[TestEnum::A]);
var_dump($map[TestEnum::A]);
?>
--EXPECT--
string(8) "a string"
string(8) "a string"

View File

@@ -1286,7 +1286,9 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
uint32_t _t = Z_TYPE_INFO_P(_z2); \
ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \
if (Z_TYPE_INFO_REFCOUNTED(_t)) { \
if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT))) { \
/* Objects reuse PERSISTENT as WEAKLY_REFERENCED */ \
if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT) \
|| GC_TYPE(_gc) == IS_OBJECT)) { \
GC_ADDREF(_gc); \
} else { \
zval_copy_ctor_func(_z1); \

View File

@@ -129,5 +129,7 @@ ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue)
ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue)));
CHECK_ZVAL_STRING(Z_STR_P(zvalue));
ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
} else {
ZEND_UNREACHABLE();
}
}