mirror of
https://github.com/php/php-src.git
synced 2026-04-13 19:14:16 +02:00
Merge branch 'PHP-7.3'
* PHP-7.3: Enforce ordering of property compare in object comparisons
This commit is contained in:
27
Zend/tests/objects_033.phpt
Normal file
27
Zend/tests/objects_033.phpt
Normal file
@@ -0,0 +1,27 @@
|
||||
--TEST--
|
||||
Ensure object comparison property order remains consistent
|
||||
--FILE--
|
||||
<?php
|
||||
|
||||
// PHP4-5.3 object semantics had child properties added to an
|
||||
// object HashTable first, then parent, then grandparent, etc...
|
||||
// As of PHP 5.4 we use a packed C array to hold properties
|
||||
// which may or may not share the same ordering.
|
||||
// In the code snippet below, the print_r() has the side-effect
|
||||
// of materializing the properties shadow HashTable which
|
||||
// if used for comparison, results in the behavior consistent
|
||||
// with pre PHP-5.4.
|
||||
// This test ensures that the first comparison yields the same
|
||||
// result without shadow table materialization.
|
||||
|
||||
class A { public $a; }
|
||||
class B extends A { public $b; }
|
||||
$a = new B(); $a->a = 0; $a->b = 1;
|
||||
$b = new B(); $b->a = 1; $b->b = 0;
|
||||
|
||||
var_dump($a < $b);
|
||||
print_r($a, true);
|
||||
var_dump($a < $b);
|
||||
--EXPECT--
|
||||
bool(false)
|
||||
bool(false)
|
||||
@@ -1514,14 +1514,11 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
|
||||
return 1; /* different classes */
|
||||
}
|
||||
if (!zobj1->properties && !zobj2->properties) {
|
||||
zval *p1, *p2, *end;
|
||||
zend_property_info *info;
|
||||
|
||||
if (!zobj1->ce->default_properties_count) {
|
||||
return 0;
|
||||
}
|
||||
p1 = zobj1->properties_table;
|
||||
p2 = zobj2->properties_table;
|
||||
end = p1 + zobj1->ce->default_properties_count;
|
||||
|
||||
/* It's enough to protect only one of the objects.
|
||||
* The second one may be referenced from the first and this may cause
|
||||
@@ -1532,7 +1529,15 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
|
||||
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
|
||||
}
|
||||
Z_PROTECT_RECURSION_P(o1);
|
||||
do {
|
||||
|
||||
ZEND_HASH_FOREACH_PTR(&zobj1->ce->properties_info, info) {
|
||||
zval *p1 = OBJ_PROP(zobj1, info->offset);
|
||||
zval *p2 = OBJ_PROP(zobj2, info->offset);
|
||||
|
||||
if (info->flags & ZEND_ACC_STATIC) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (Z_TYPE_P(p1) != IS_UNDEF) {
|
||||
if (Z_TYPE_P(p2) != IS_UNDEF) {
|
||||
zval result;
|
||||
@@ -1555,9 +1560,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
p1++;
|
||||
p2++;
|
||||
} while (p1 != end);
|
||||
} ZEND_HASH_FOREACH_END();
|
||||
|
||||
Z_UNPROTECT_RECURSION_P(o1);
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user