Skip to content

Commit 91e1df7

Browse files
committed
Fix bug #62373 (serialize() generates wrong reference to the object)
1 parent ad64195 commit 91e1df7

File tree

2 files changed

+27
-5
lines changed

2 files changed

+27
-5
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Bug #62373 (serialize() generates wrong reference to the object)
3+
--FILE--
4+
<?php
5+
class A {}
6+
class B {}
7+
8+
$size_of_ce = (((int)(log(PHP_INT_MAX) / log(2)) + 1 == 32 ? 368: 680) + 15) & ~15;
9+
$dummy = array();
10+
$b = new B();
11+
$period = $size_of_ce << 5;
12+
for ($i = 0; $i < $period * 3; $i++) {
13+
$a = new A();
14+
$s = unserialize(serialize(array($b, $a)));
15+
if ($s[0] === $s[1]) {
16+
echo "OOPS\n";
17+
break;
18+
}
19+
$dummy[] = $a;
20+
}
21+
22+
echo "OK\n";
23+
?>
24+
--EXPECT--
25+
OK

ext/standard/var.c

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -541,12 +541,9 @@ static inline int php_add_var_hash(HashTable *var_hash, zval *var, void *var_old
541541

542542
/* relies on "(long)" being a perfect hash function for data pointers,
543543
* however the actual identity of an object has had to be determined
544-
* by its object handle and the class entry since 5.0. */
544+
* by its object handle since 5.0. */
545545
if ((Z_TYPE_P(var) == IS_OBJECT) && Z_OBJ_HT_P(var)->get_class_entry) {
546-
p = smart_str_print_long(id + sizeof(id) - 1,
547-
(((size_t)Z_OBJCE_P(var) << 5)
548-
| ((size_t)Z_OBJCE_P(var) >> (sizeof(long) * 8 - 5)))
549-
+ (long) Z_OBJ_HANDLE_P(var));
546+
p = smart_str_print_long(id + sizeof(id) - 1, (long) Z_OBJ_HANDLE_P(var));
550547
*(--p) = 'O';
551548
len = id + sizeof(id) - 1 - p;
552549
} else {

0 commit comments

Comments
 (0)