1
0
mirror of https://github.com/php/php-src.git synced 2026-03-24 00:02:20 +01:00

Fix EG(current_execute_data) introduced in 1292037

Fixes OSS-Fuzz #456317305
This commit is contained in:
Ilija Tovilo
2025-10-30 14:04:09 +01:00
parent 6fe40de6e3
commit 5518165499
3 changed files with 45 additions and 13 deletions

View File

@@ -0,0 +1,25 @@
--TEST--
OSS-Fuzz #456317305: EG(current_execute_data) NULL pointer violation
--FILE--
<?php
class C {
public function __destruct() {
static $again = true;
if ($again) {
$again = false;
$c = new C;
}
throw new Exception;
}
}
$c = new C;
?>
--EXPECTF--
Fatal error: Uncaught Exception in %s:%d
Stack trace:
#0 [internal function]: C->__destruct()
#1 {main}
thrown in %s on line %d

View File

@@ -321,9 +321,11 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
zend_object *old_exception = NULL;
const zend_op *old_opline_before_exception = NULL;
if (EG(exception)) {
EG(current_execute_data)->opline = EG(opline_before_exception);
if (EG(current_execute_data)) {
EG(current_execute_data)->opline = EG(opline_before_exception);
old_opline_before_exception = EG(opline_before_exception);
}
old_exception = EG(exception);
old_opline_before_exception = EG(opline_before_exception);
EG(exception) = NULL;
}
@@ -335,8 +337,10 @@ static void zend_generator_dtor_storage(zend_object *object) /* {{{ */
zend_generator_resume(generator);
if (old_exception) {
EG(current_execute_data)->opline = EG(exception_op);
EG(opline_before_exception) = old_opline_before_exception;
if (EG(current_execute_data)) {
EG(current_execute_data)->opline = EG(exception_op);
EG(opline_before_exception) = old_opline_before_exception;
}
if (EG(exception)) {
zend_exception_set_previous(EG(exception), old_exception);
} else {

View File

@@ -100,7 +100,7 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
if (destructor) {
zend_object *old_exception;
const zend_op *old_opline_before_exception;
const zend_op *old_opline_before_exception = NULL;
if (destructor->op_array.fn_flags & (ZEND_ACC_PRIVATE|ZEND_ACC_PROTECTED)) {
if (destructor->op_array.fn_flags & ZEND_ACC_PRIVATE) {
@@ -159,14 +159,15 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
if (EG(exception) == object) {
zend_error_noreturn(E_CORE_ERROR, "Attempt to destruct pending exception");
} else {
if (EG(current_execute_data)
&& EG(current_execute_data)->func
&& ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
zend_rethrow_exception(EG(current_execute_data));
if (EG(current_execute_data)) {
if (EG(current_execute_data)->func
&& ZEND_USER_CODE(EG(current_execute_data)->func->common.type)) {
zend_rethrow_exception(EG(current_execute_data));
}
EG(current_execute_data)->opline = EG(opline_before_exception);
old_opline_before_exception = EG(opline_before_exception);
}
EG(current_execute_data)->opline = EG(opline_before_exception);
old_exception = EG(exception);
old_opline_before_exception = EG(opline_before_exception);
EG(exception) = NULL;
}
}
@@ -174,8 +175,10 @@ ZEND_API void zend_objects_destroy_object(zend_object *object)
zend_call_known_instance_method_with_0_params(destructor, object, NULL);
if (old_exception) {
EG(current_execute_data)->opline = EG(exception_op);
EG(opline_before_exception) = old_opline_before_exception;
if (EG(current_execute_data)) {
EG(current_execute_data)->opline = EG(exception_op);
EG(opline_before_exception) = old_opline_before_exception;
}
if (EG(exception)) {
zend_exception_set_previous(EG(exception), old_exception);
} else {