diff --git a/NEWS b/NEWS index 2beb7bea90833..56e0f5c5179e0 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,8 @@ PHP NEWS - Core: . Fix GH-14978 (The xmlreader extension phpize build). (Peter Kokot) + . Throw Error exception when encountering recursion during comparison, rather + than fatal error. (ilutov) - BCMath: . Adjust bcround()'s $mode parameter to only accept the RoundingMode diff --git a/UPGRADING b/UPGRADING index 3940180fe01ab..4450aeac8e7c7 100644 --- a/UPGRADING +++ b/UPGRADING @@ -31,6 +31,8 @@ PHP 8.4 UPGRADE NOTES . The type of PHP_DEBUG and PHP_ZTS constants changed to bool. . The name of uploaded files and files created by the tempnam() function are now 13 bytes longer. Total length is platform-dependent. + . Encountering recursion during comparison now results in a Error exception, + rather than a fatal error. - DOM: . Added DOMNode::compareDocumentPosition() and DOMNode::DOCUMENT_POSITION_* diff --git a/Zend/tests/bug63882.phpt b/Zend/tests/bug63882.phpt index 0cc1babd49bdf..801f1b1e07eaf 100644 --- a/Zend/tests/bug63882.phpt +++ b/Zend/tests/bug63882.phpt @@ -9,7 +9,12 @@ $testobj2 = new Test; $testobj1->x = $testobj1; $testobj2->x = $testobj2; -var_dump($testobj1 == $testobj2); +try { + var_dump($testobj1 == $testobj2); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} + ?> ---EXPECTF-- -Fatal error: Nesting level too deep - recursive dependency? in %sbug63882.php on line 9 +--EXPECT-- +Nesting level too deep - recursive dependency? diff --git a/Zend/tests/recursive_array_comparison.phpt b/Zend/tests/recursive_array_comparison.phpt new file mode 100644 index 0000000000000..53cc9736030d0 --- /dev/null +++ b/Zend/tests/recursive_array_comparison.phpt @@ -0,0 +1,21 @@ +--TEST-- +Comparison of a recursive array throws a catchable error +--FILE-- +getMessage(), "\n"; +} +try { + [[]] === $a; +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +var_dump($a === $a); +?> +--EXPECT-- +Nesting level too deep - recursive dependency? +Nesting level too deep - recursive dependency? +bool(true) diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index 220e25c358f7d..c954d2fcf415d 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -3180,7 +3180,8 @@ ZEND_API int zend_hash_compare(HashTable *ht1, HashTable *ht2, compare_func_t co * false recursion detection. */ if (UNEXPECTED(GC_IS_RECURSIVE(ht1))) { - zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); + zend_throw_error(NULL, "Nesting level too deep - recursive dependency?"); + return ZEND_UNCOMPARABLE; } GC_TRY_PROTECT_RECURSION(ht1); diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 2b9e43425ef85..aa2cd0fb3d5b2 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -1985,7 +1985,8 @@ ZEND_API int zend_std_compare_objects(zval *o1, zval *o2) /* {{{ */ */ /* use bitwise OR to make only one conditional jump */ if (UNEXPECTED(Z_IS_RECURSIVE_P(o1))) { - zend_error_noreturn(E_ERROR, "Nesting level too deep - recursive dependency?"); + zend_throw_error(NULL, "Nesting level too deep - recursive dependency?"); + return ZEND_UNCOMPARABLE; } Z_PROTECT_RECURSION_P(o1);