Skip to content

Commit 7b9d97f

Browse files
committed
Throw error for recursive comparison, instead of fatal
I don't understand the rationale of fatal erroring here. It seems this should properly unprotect the compared elements when returning up the stack. Related to GH-14980
1 parent ead679e commit 7b9d97f

File tree

4 files changed

+33
-5
lines changed

4 files changed

+33
-5
lines changed

Zend/tests/bug63882.phpt

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ $testobj2 = new Test;
99
$testobj1->x = $testobj1;
1010
$testobj2->x = $testobj2;
1111

12-
var_dump($testobj1 == $testobj2);
12+
try {
13+
var_dump($testobj1 == $testobj2);
14+
} catch (Error $e) {
15+
echo $e->getMessage(), "\n";
16+
}
17+
1318
?>
14-
--EXPECTF--
15-
Fatal error: Nesting level too deep - recursive dependency? in %sbug63882.php on line 9
19+
--EXPECT--
20+
Nesting level too deep - recursive dependency?
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Comparison of a recursive array leads throws a catchable error
3+
--FILE--
4+
<?php
5+
$a = [&$a];
6+
try {
7+
$a === [[]];
8+
} catch (Error $e) {
9+
echo $e->getMessage(), "\n";
10+
}
11+
try {
12+
[[]] === $a;
13+
} catch (Error $e) {
14+
echo $e->getMessage(), "\n";
15+
}
16+
var_dump($a === $a);
17+
?>
18+
--EXPECT--
19+
Nesting level too deep - recursive dependency?
20+
Nesting level too deep - recursive dependency?
21+
bool(true)

Zend/zend_hash.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3180,7 +3180,8 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co
31803180
* false recursion detection.
31813181
*/
31823182
if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) {
3183-
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
3183+
zend_throw_error(NULL, "Nesting level too deep - recursive dependency?");
3184+
return ZEND_UNCOMPARABLE;
31843185
}
31853186

31863187
GC_TRY_PROTECT_RECURSION(ht1);

Zend/zend_object_handlers.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1988,7 +1988,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */
19881988
*/
19891989
/* use bitwise OR to make only one conditional jump */
19901990
if (UNEXPECTED(Z_IS_RECURSIVE_P(o1))) {
1991-
zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?");
1991+
zend_throw_error(NULL, "Nesting level too deep - recursive dependency?");
1992+
return ZEND_UNCOMPARABLE;
19921993
}
19931994
Z_PROTECT_RECURSION_P(o1);
19941995

0 commit comments

Comments
 (0)