Skip to content

Commit bd3e536

Browse files
committed
Fixed bug #81514
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).
1 parent c9fb384 commit bd3e536

File tree

4 files changed

+25
-1
lines changed

4 files changed

+25
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ PHP NEWS
99
. Fixed bug #75941 (Fix compile failure on Solaris with clang). (Jaromír
1010
Doleček)
1111
. Fixed bug #81380 (Observer may not be initialized properly). (krakjoe)
12+
. Fixed bug #81514 (Using Enum as key in WeakMap triggers GC + SegFault).
13+
(Nikita)
1214

1315
- Date:
1416
. Fixed bug #81504 (Incorrect timezone transition details for POSIX data).

Zend/tests/enum/weak-map.phpt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Use enum as WeakMap key
3+
--FILE--
4+
<?php
5+
6+
enum TestEnum {
7+
case A;
8+
}
9+
10+
$map = new WeakMap();
11+
$map[TestEnum::A] = 'a string';
12+
var_dump($map[TestEnum::A]);
13+
var_dump($map[TestEnum::A]);
14+
15+
?>
16+
--EXPECT--
17+
string(8) "a string"
18+
string(8) "a string"

Zend/zend_types.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1286,7 +1286,9 @@ static zend_always_inline uint32_t zval_delref_p(zval* pz) {
12861286
uint32_t _t = Z_TYPE_INFO_P(_z2); \
12871287
ZVAL_COPY_VALUE_EX(_z1, _z2, _gc, _t); \
12881288
if (Z_TYPE_INFO_REFCOUNTED(_t)) { \
1289-
if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT))) { \
1289+
/* Objects reuse PERSISTENT as WEAKLY_REFERENCED */ \
1290+
if (EXPECTED(!(GC_FLAGS(_gc) & GC_PERSISTENT) \
1291+
|| GC_TYPE(_gc) == IS_OBJECT)) { \
12901292
GC_ADDREF(_gc); \
12911293
} else { \
12921294
zval_copy_ctor_func(_z1); \

Zend/zend_variables.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,5 +129,7 @@ ZEND_API void ZEND_FASTCALL zval_copy_ctor_func(zval *zvalue)
129129
ZEND_ASSERT(!ZSTR_IS_INTERNED(Z_STR_P(zvalue)));
130130
CHECK_ZVAL_STRING(Z_STR_P(zvalue));
131131
ZVAL_NEW_STR(zvalue, zend_string_dup(Z_STR_P(zvalue), 0));
132+
} else {
133+
ZEND_UNREACHABLE();
132134
}
133135
}

0 commit comments

Comments
 (0)