Skip to content
This repository was archived by the owner on Jul 7, 2018. It is now read-only.

Commit 76aa39c

Browse files
committed
Fix bug when object handle reused but previous state was not clean
1 parent 4d6b82a commit 76aa39c

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

php_ref_reference.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,10 @@ static void php_ref_maybe_restore_handlers(php_ref_referent_t *referent)
152152
return;
153153
}
154154

155-
Z_OBJ(referent->this_ptr)->handlers = referent->original_handlers;
156-
referent->original_handlers = NULL;
155+
if (referent->original_handlers) {
156+
Z_OBJ(referent->this_ptr)->handlers = referent->original_handlers;
157+
referent->original_handlers = NULL;
158+
}
157159
}
158160

159161
void php_ref_referent_object_dtor_obj(zend_object *object)
@@ -234,6 +236,10 @@ void php_ref_referent_abstract_references_ht_dtor(zval *zv)
234236
if (reference->referent) {
235237
reference->referent->tracked--;
236238
php_ref_maybe_restore_handlers(reference->referent);
239+
240+
if (!reference->referent->tracked) {
241+
zend_hash_index_del(PHP_REF_G(referents), reference->referent->handle);
242+
}
237243
}
238244

239245
/* clean links to ht & release callbacks as we don't need them already*/
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
--TEST--
2+
Ref\WeakReference - reference should work for newly create tracked objects with same handles as previously tracked objects
3+
--SKIPIF--
4+
<?php if (!extension_loaded("ref")) print "skip"; ?>
5+
--FILE--
6+
<?php
7+
8+
use Ref\WeakReference;
9+
10+
/** @var \Testsuite $helper */
11+
$helper = require '.testsuite.php';
12+
13+
14+
class Test {
15+
public $storage = [];
16+
17+
public function put($key, $value, string $hash)
18+
{
19+
$key = new WeakReference($key, function () use ($hash) {
20+
unset($this->storage[$hash]);
21+
});
22+
23+
$value = new WeakReference($value, function () use ($hash) {
24+
unset($this->storage[$hash]);
25+
});
26+
27+
$this->storage[$hash] = [$key, $value];
28+
}
29+
}
30+
31+
32+
$map = new Test();
33+
34+
$key_1 = new stdClass();
35+
$value_1 = new stdClass();
36+
37+
$key_2 = new stdClass();
38+
$value_2 = new stdClass();
39+
40+
$map->put($key_1, $value_1, 'test_1');
41+
$map->put($key_2, $value_2, 'test_2');
42+
43+
$helper->assert('count', 2, count($map->storage));
44+
45+
46+
$key_1 = null;
47+
$helper->assert('count', 1, count($map->storage));
48+
49+
50+
$value_2 = null;
51+
$helper->assert('count', 0, count($map->storage));
52+
53+
$key_1 = new stdClass();
54+
$value_1 = new stdClass();
55+
56+
$key_2 = new stdClass();
57+
$value_2 = new stdClass();
58+
59+
$map->put($key_1, $value_1, 'test_1');
60+
$map->put($key_2, $value_2, 'test_2');
61+
62+
$helper->assert('count', 2, count($map->storage));
63+
64+
$key_1 = null;
65+
$helper->assert('count', 1, count($map->storage));
66+
67+
$value_2 = null;
68+
$helper->assert('count', 0, count($map->storage));
69+
70+
71+
?>
72+
--EXPECT--
73+
count: ok
74+
count: ok
75+
count: ok
76+
count: ok
77+
count: ok
78+
count: ok

0 commit comments

Comments
 (0)