From b5c09b1a61872d5408cc5c4f7548735a9d4d2ef6 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Tue, 8 Oct 2024 15:30:13 +0200 Subject: [PATCH] Fix exception in assert() callback with bail enabled Fixes GH-16293 Closes GH-16304 --- NEWS | 4 ++++ Zend/tests/gh16293_001.phpt | 19 +++++++++++++++++++ Zend/tests/gh16293_002.phpt | 19 +++++++++++++++++++ ext/standard/assert.c | 5 +++++ 4 files changed, 47 insertions(+) create mode 100644 Zend/tests/gh16293_001.phpt create mode 100644 Zend/tests/gh16293_002.phpt diff --git a/NEWS b/NEWS index bceee09997c..ae2734bda0c 100644 --- a/NEWS +++ b/NEWS @@ -57,6 +57,10 @@ PHP NEWS - SPL: . Fixed bug GH-16337 (Use-after-free in SplHeap). (nielsdos) +- Standard: + . Fixed bug GH-16293 (Failed assertion when throwing in assert() callback with + bail enabled). (ilutov) + - XMLReader: . Fixed bug GH-16292 (Segmentation fault in ext/xmlreader/php_xmlreader.c). (nielsdos) diff --git a/Zend/tests/gh16293_001.phpt b/Zend/tests/gh16293_001.phpt new file mode 100644 index 00000000000..a43c9adc45e --- /dev/null +++ b/Zend/tests/gh16293_001.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-16293: Exception in assert() callback with bail enabled +--FILE-- + +--EXPECTF-- +Warning: assert(): assert(false) failed in %s on line %d + +Warning: Uncaught Error: Invalid callback f1, function "f1" not found or invalid function name in %s:%d +Stack trace: +#0 %s(%d): assert(false, 'assert(false)') +#1 {main} + thrown in %s on line %d diff --git a/Zend/tests/gh16293_002.phpt b/Zend/tests/gh16293_002.phpt new file mode 100644 index 00000000000..a0cd78eedbb --- /dev/null +++ b/Zend/tests/gh16293_002.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-16293: Exception in assert() callback with bail enabled +--FILE-- + +--EXPECTF-- +Warning: assert(): assert(false) failed in %s on line %d + +Warning: Uncaught Exception: Boo in %s:%d +Stack trace: +%a diff --git a/ext/standard/assert.c b/ext/standard/assert.c index 1c5108b94e5..f318b1c8340 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -195,6 +195,11 @@ PHP_FUNCTION(assert) } if (ASSERTG(bail)) { + if (EG(exception)) { + /* The callback might have thrown. Use E_WARNING to print the + * exception so we can avoid bailout and use unwind_exit. */ + zend_exception_error(EG(exception), E_WARNING); + } zend_throw_unwind_exit(); RETURN_THROWS(); } else {