com php-src: Fixed incorrect recursion detection: Zend/zend_h ash.c Zend/zend_object_handlers.c tests/lang/operat
ors/operator_identical_recusion-01.phpt

From: Date: Fri, 06 Oct 2017 08:47:11 +0000
Subject: com php-src: Fixed incorrect recursion detection: Zend/zend_h ash.c Zend/zend_object_handlers.c tests/lang/operat
ors/operator_identical_recusion-01.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-99641@lists.php.net to get a copy of this message
Commit: f18638ca2daf0938723a5197a1e7dcd4e7f384f8 Author: Dmitry Stogov <dmitry@zend.com> Fri, 6 Oct 2017 11:47:11 +0300 Parents: 254b74b85f0d9467c937ccee8aab02e31729d49b Branches: master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=f18638ca2daf0938723a5197a1e7dcd4e7f384f8 Log: Fixed incorrect recursion detection Changed paths: M Zend/zend_hash.c M Zend/zend_object_handlers.c A tests/lang/operators/operator_identical_recusion-01.phpt Diff: diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 07dcd26..d629c09 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -2369,24 +2369,21 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co return 0; } - /* use bitwise OR to make only one conditional jump */ - if (UNEXPECTED(GC_IS_RECURSIVE(ht1) | GC_IS_RECURSIVE(ht2))) { + /* It's enough to protect only one of the arrays. + * The second one may be referenced from the first and this may cause + * false recursion detection. + */ + if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) { zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); } if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { GC_PROTECT_RECURSION(ht1); } - if (!(GC_FLAGS(ht2) & GC_IMMUTABLE)) { - GC_PROTECT_RECURSION(ht2); - } result = zend_hash_compare_impl(ht1, ht2, compar, ordered); if (!(GC_FLAGS(ht1) & GC_IMMUTABLE)) { GC_UNPROTECT_RECURSION(ht1); } - if (!(GC_FLAGS(ht2) & GC_IMMUTABLE)) { - GC_UNPROTECT_RECURSION(ht2); - } return result; } diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index f1412ef..6e709cd 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1448,12 +1448,15 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ 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 + * false recursion detection. + */ /* use bitwise OR to make only one conditional jump */ - if (UNEXPECTED(Z_IS_RECURSIVE_P(o1) | Z_IS_RECURSIVE_P(o2))) { + if (UNEXPECTED(Z_IS_RECURSIVE_P(o1))) { zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); } Z_PROTECT_RECURSION_P(o1); - Z_PROTECT_RECURSION_P(o2); do { if (Z_TYPE_P(p1) != IS_UNDEF) { if (Z_TYPE_P(p2) != IS_UNDEF) { @@ -1461,23 +1464,19 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ if (compare_function(&result, p1, p2)==FAILURE) { Z_UNPROTECT_RECURSION_P(o1); - Z_UNPROTECT_RECURSION_P(o2); return 1; } if (Z_LVAL(result) != 0) { Z_UNPROTECT_RECURSION_P(o1); - Z_UNPROTECT_RECURSION_P(o2); return Z_LVAL(result); } } else { Z_UNPROTECT_RECURSION_P(o1); - Z_UNPROTECT_RECURSION_P(o2); return 1; } } else { if (Z_TYPE_P(p2) != IS_UNDEF) { Z_UNPROTECT_RECURSION_P(o1); - Z_UNPROTECT_RECURSION_P(o2); return 1; } } @@ -1485,7 +1484,6 @@ static int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ p2++; } while (p1 != end); Z_UNPROTECT_RECURSION_P(o1); - Z_UNPROTECT_RECURSION_P(o2); return 0; } else { if (!zobj1->properties) { diff --git a/tests/lang/operators/operator_identical_recusion-01.phpt b/tests/lang/operators/operator_identical_recusion-01.phpt new file mode 100644 index 0000000..3680e30 --- /dev/null +++ b/tests/lang/operators/operator_identical_recusion-01.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test === operator : False recursion detection +--FILE-- +<?php +$n = 0; +$a = [[$n]]; +$b = [&$a]; +var_dump($a === $b); +--EXPECT-- +bool(false) \ No newline at end of file

« previous php.cvs (#99641) next »