1
0
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:
Sara Golemon
2018-09-10 08:56:19 -04:00
2 changed files with 39 additions and 8 deletions

View 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)

View File

@@ -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 {