Skip to content

Commit f9fed57

Browse files
committed
Fix WeakMap temporary key dimension fetch
1 parent a11e54e commit f9fed57

2 files changed

Lines changed: 73 additions & 0 deletions

File tree

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
--TEST--
2+
WeakMap dimension reference with a temporary key
3+
--FILE--
4+
<?php
5+
$wm = new WeakMap;
6+
try {
7+
$r = &$wm[new stdClass];
8+
} catch (Error $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
var_dump(count($wm));
12+
13+
try {
14+
$wm[new stdClass][] = 1;
15+
} catch (Error $e) {
16+
echo $e->getMessage(), "\n";
17+
}
18+
var_dump(count($wm));
19+
20+
$key = new stdClass;
21+
$wm[$key] = 2;
22+
$keys = [$key];
23+
$r = &$wm[array_pop($keys)];
24+
$r = 3;
25+
var_dump($wm[$key]);
26+
27+
$key = new stdClass;
28+
$wm[$key] = 1;
29+
$keys = [$key];
30+
unset($key);
31+
try {
32+
$r = &$wm[array_pop($keys)];
33+
} catch (Error $e) {
34+
echo $e->getMessage(), "\n";
35+
}
36+
var_dump(count($wm));
37+
38+
class K {
39+
function __destruct() {
40+
$GLOBALS['wm'] = null;
41+
}
42+
}
43+
44+
$wm = new WeakMap;
45+
try {
46+
$wm[new K][] = str_repeat("x", 10);
47+
} catch (Error $e) {
48+
echo $e->getMessage(), "\n";
49+
}
50+
var_dump($wm);
51+
?>
52+
--EXPECT--
53+
Cannot modify a WeakMap dimension using a temporary object key
54+
int(0)
55+
int(3)
56+
Cannot modify a WeakMap dimension using a temporary object key
57+
int(0)
58+
Cannot modify a WeakMap dimension using a temporary object key
59+
int(0)
60+
Cannot modify a WeakMap dimension using a temporary object key
61+
NULL
62+
?>

‎Zend/zend_weakrefs.c‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ static void zend_weakmap_free_obj(zend_object *object)
354354

355355
static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int type, zval *rv)
356356
{
357+
zval *orig_offset = offset;
358+
357359
if (offset == NULL) {
358360
zend_throw_error(NULL, "Cannot append to WeakMap");
359361
return NULL;
@@ -369,6 +371,15 @@ static zval *zend_weakmap_read_dimension(zend_object *object, zval *offset, int
369371
zend_object *obj_addr = Z_OBJ_P(offset);
370372
zval *zv = zend_hash_index_find(&wm->ht, zend_object_to_weakref_key(obj_addr));
371373
if (type == BP_VAR_W || type == BP_VAR_RW) {
374+
const zend_execute_data *ex = EG(current_execute_data);
375+
if (UNEXPECTED(GC_REFCOUNT(obj_addr) == 1)
376+
&& ex && ex->func && ZEND_USER_CODE(ex->func->type)
377+
&& ex->opline
378+
&& (ex->opline->op2_type & (IS_TMP_VAR | IS_VAR))
379+
&& orig_offset == ZEND_CALL_VAR(ex, ex->opline->op2.var)) {
380+
zend_throw_error(NULL, "Cannot modify a WeakMap dimension using a temporary object key");
381+
return NULL;
382+
}
372383
if (zv == NULL) {
373384
zval value;
374385
zend_weakref_register(obj_addr, ZEND_WEAKREF_ENCODE(&wm->ht, ZEND_WEAKREF_TAG_MAP));

0 commit comments

Comments
 (0)