From a26a107aae3f202580e5dfba8ecf735a29c907d4 Mon Sep 17 00:00:00 2001 From: Sara Golemon Date: Sat, 11 Aug 2018 11:19:28 -0400 Subject: [PATCH] Enforce ordering of property compare in object comparisons --- Zend/tests/objects_033.phpt | 27 +++++++++++++++++++++++++++ Zend/zend_object_handlers.c | 20 ++++++++++++-------- 2 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 Zend/tests/objects_033.phpt diff --git a/Zend/tests/objects_033.phpt b/Zend/tests/objects_033.phpt new file mode 100644 index 0000000000..365edc3832 --- /dev/null +++ b/Zend/tests/objects_033.phpt @@ -0,0 +1,27 @@ +--TEST-- +Ensure object comparison property order remains consistent +--FILE-- +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) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index fde7b1204c..aa2f5be846 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -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 { -- 2.40.0