Skip to content

Commit

Permalink
MFH: Fix #46241 (stacked error_handlers, error_handling in general)
Browse files Browse the repository at this point in the history
  • Loading branch information
colder committed Nov 19, 2008
1 parent 202426a commit 3919b16
Show file tree
Hide file tree
Showing 25 changed files with 182 additions and 47 deletions.
2 changes: 2 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ PHP NEWS
endian systems). (Scott)
- Fixed bug #46285 (lastInsertId() returns "0" when a deferenced PDOStatement is
executed). (Johannes)
- Fixed bug #46241 (stacked error handlers, error handling in genera).
(Etienne)
- Fixed bug #46238 (Segmentation fault on static call with empty string method).
(Felipe)
- Fixed bug #46205 (Closure - Memory leaks when ReflectionException is thrown).
Expand Down
2 changes: 0 additions & 2 deletions Zend/tests/bug46196.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
Test restore_error_handler() function : bug #46196
--CREDITS--
Olivier Doucet
--XFAIL--
This test will fail until bug #46196 is fixed
--FILE--
<?php
/* Prototype : void restore_error_handler(void)
Expand Down
50 changes: 50 additions & 0 deletions Zend/tests/bug46241.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
--TEST--
Bug #46241 (error handler stacks)
--FILE--
<?php

class ErrorHandling
{

public function errorHandler1( $errno, $errstr )
{
echo "Caught on first level: '$errstr'\n";
return true;
}

public function errorHandler2( $errno, $errstr )
{
echo "Caught on second level: '$errstr'\n";
return true;
}
}

$err = new ErrorHandling();

set_error_handler( array( $err, 'errorHandler1' ) );
set_error_handler( array( $err, 'errorHandler2' ) );

trigger_error( 'Foo', E_USER_WARNING );

function errorHandler1( $errno, $errstr )
{
echo "Caught on first level: '$errstr'\n";
return true;
}

function errorHandler2( $errno, $errstr )
{
echo "Caught on second level: '$errstr'\n";
return true;
}

set_error_handler( 'errorHandler1' );
set_error_handler( 'errorHandler2' );

trigger_error( 'Foo', E_USER_WARNING );
?>
==END==
--EXPECT--
Caught on second level: 'Foo'
Caught on second level: 'Foo'
==END==
6 changes: 0 additions & 6 deletions Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -943,14 +943,11 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
EG(opline_ptr) = original_opline_ptr;
} else if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
int call_via_handler = (EX(function_state).function->common.fn_flags & ZEND_ACC_CALL_VIA_HANDLER) != 0;
zend_error_handling error_handling;
zend_save_error_handling(&error_handling TSRMLS_CC);
ALLOC_INIT_ZVAL(*fci->retval_ptr_ptr);
if (EX(function_state).function->common.scope) {
EG(scope) = EX(function_state).function->common.scope;
}
((zend_internal_function *) EX(function_state).function)->handler(fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, (fci->object_pp?*fci->object_pp:NULL), 1 TSRMLS_CC);
zend_restore_error_handling(&error_handling TSRMLS_CC);
/* We shouldn't fix bad extensions here,
because it can break proper ones (Bug #34045)
if (!EX(function_state).function->common.return_reference)
Expand All @@ -971,10 +968,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS

/* Not sure what should be done here if it's a static method */
if (fci->object_pp) {
zend_error_handling error_handling;
zend_save_error_handling(&error_handling TSRMLS_CC);
Z_OBJ_HT_PP(fci->object_pp)->call_method(EX(function_state).function->common.function_name, fci->param_count, *fci->retval_ptr_ptr, fci->retval_ptr_ptr, *fci->object_pp, 1 TSRMLS_CC);
zend_restore_error_handling(&error_handling TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
Expand Down
6 changes: 0 additions & 6 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2270,7 +2270,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);

if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
zend_error_handling error_handling;
ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
Expand All @@ -2285,14 +2284,12 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
arg_count--;
}
}
zend_save_error_handling(&error_handling TSRMLS_CC);
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
}
zend_restore_error_handling(&error_handling TSRMLS_CC);

if (!RETURN_VALUE_USED(opline)) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
Expand Down Expand Up @@ -2340,10 +2337,7 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)

/* Not sure what should be done here if it's a static method */
if (EX(object)) {
zend_error_handling error_handling;
zend_save_error_handling(&error_handling TSRMLS_CC);
Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
zend_restore_error_handling(&error_handling TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
Expand Down
6 changes: 0 additions & 6 deletions Zend/zend_vm_execute.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);

if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
zend_error_handling error_handling;
ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
Expand All @@ -309,14 +308,12 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
arg_count--;
}
}
zend_save_error_handling(&error_handling TSRMLS_CC);
if (!zend_execute_internal) {
/* saves one function call if zend_execute_internal is not used */
((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
} else {
zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
}
zend_restore_error_handling(&error_handling TSRMLS_CC);

if (!RETURN_VALUE_USED(opline)) {
zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
Expand Down Expand Up @@ -364,10 +361,7 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR

/* Not sure what should be done here if it's a static method */
if (EX(object)) {
zend_error_handling error_handling;
zend_save_error_handling(&error_handling TSRMLS_CC);
Z_OBJ_HT_P(EX(object))->call_method(EX(function_state).function->common.function_name, opline->extended_value, EX_T(opline->result.u.var).var.ptr, &EX_T(opline->result.u.var).var.ptr, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
zend_restore_error_handling(&error_handling TSRMLS_CC);
} else {
zend_error_noreturn(E_ERROR, "Cannot call overloaded function for non-object");
}
Expand Down
19 changes: 14 additions & 5 deletions ext/date/php_date.c
Original file line number Diff line number Diff line change
Expand Up @@ -2420,12 +2420,13 @@ PHP_METHOD(DateTime, __construct)
zval *timezone_object = NULL;
char *time_str = NULL;
int time_str_len = 0;

zend_error_handling error_handling;

zend_replace_error_handling(EH_THROW, NULL, NULL TSRMLS_CC);
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|sO", &time_str, &time_str_len, &timezone_object, date_ce_timezone)) {
date_initialize(zend_object_store_get_object(getThis() TSRMLS_CC), time_str, time_str_len, NULL, timezone_object, 1 TSRMLS_CC);
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
}
/* }}} */

Expand Down Expand Up @@ -3094,8 +3095,9 @@ PHP_METHOD(DateTimeZone, __construct)
int tz_len;
timelib_tzinfo *tzi = NULL;
php_timezone_obj *tzobj;
zend_error_handling error_handling;

zend_replace_error_handling(EH_THROW, NULL, NULL TSRMLS_CC);
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &tz, &tz_len)) {
if (SUCCESS == timezone_initialize(&tzi, tz TSRMLS_CC)) {
tzobj = zend_object_store_get_object(getThis() TSRMLS_CC);
Expand All @@ -3106,6 +3108,7 @@ PHP_METHOD(DateTimeZone, __construct)
ZVAL_NULL(getThis());
}
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
}
/* }}} */

Expand Down Expand Up @@ -3437,8 +3440,9 @@ PHP_METHOD(DateInterval, __construct)
int interval_string_length;
php_interval_obj *diobj;
timelib_rel_time *reltime;
zend_error_handling error_handling;

zend_replace_error_handling(EH_THROW, NULL, NULL TSRMLS_CC);
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &interval_string, &interval_string_length) == SUCCESS) {
if (date_interval_initialize(&reltime, interval_string, interval_string_length TSRMLS_CC) == SUCCESS) {
diobj = zend_object_store_get_object(getThis() TSRMLS_CC);
Expand All @@ -3448,6 +3452,7 @@ PHP_METHOD(DateInterval, __construct)
ZVAL_NULL(getThis());
}
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
}
/* }}} */

Expand Down Expand Up @@ -3590,12 +3595,14 @@ PHP_METHOD(DatePeriod, __construct)
char *isostr = NULL;
int isostr_len = 0;
timelib_time *clone;
zend_error_handling error_handling;

zend_replace_error_handling(EH_THROW, NULL, NULL TSRMLS_CC);
zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOl|l", &start, date_ce_date, &interval, date_ce_interval, &recurrences, &options) == FAILURE) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "OOO|l", &start, date_ce_date, &interval, date_ce_interval, &end, date_ce_date, &options) == FAILURE) {
if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &isostr, &isostr_len, &options) == FAILURE) {
php_error_docref(NULL TSRMLS_CC, E_WARNING, "This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.");
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}
}
Expand Down Expand Up @@ -3662,6 +3669,8 @@ PHP_METHOD(DatePeriod, __construct)
dpobj->recurrences = recurrences + dpobj->include_start_date;

dpobj->initialized = 1;

zend_restore_error_handling(&error_handling TSRMLS_CC);
}
/* }}} */

Expand Down
1 change: 1 addition & 0 deletions ext/dom/attr.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ PHP_METHOD(domattr, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_attr_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/cdatasection.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ PHP_METHOD(domcdatasection, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_cdatasection_class_entry, &value, &value_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/comment.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ PHP_METHOD(domcomment, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_comment_class_entry, &value, &value_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/document.c
Original file line number Diff line number Diff line change
Expand Up @@ -1441,6 +1441,7 @@ PHP_METHOD(domdocument, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ss", &id, dom_document_class_entry, &version, &version_len, &encoding, &encoding_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/documentfragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ PHP_METHOD(domdocumentfragment, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &id, dom_documentfragment_class_entry) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/element.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ PHP_METHOD(domelement, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s!s", &id, dom_element_class_entry, &name, &name_len, &value, &value_len, &uri, &uri_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}
zend_restore_error_handling(&error_handling TSRMLS_CC);
Expand Down
1 change: 1 addition & 0 deletions ext/dom/entityreference.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ PHP_METHOD(domentityreference, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &id, dom_entityreference_class_entry, &name, &name_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/processinginstruction.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ PHP_METHOD(domprocessinginstruction, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|s", &id, dom_processinginstruction_class_entry, &name, &name_len, &value, &value_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/text.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ PHP_METHOD(domtext, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|s", &id, dom_text_class_entry, &value, &value_len) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
1 change: 1 addition & 0 deletions ext/dom/xpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ PHP_METHOD(domxpath, __construct)

zend_replace_error_handling(EH_THROW, dom_domexception_class_entry, &error_handling TSRMLS_CC);
if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "OO", &id, dom_xpath_class_entry, &doc, dom_document_class_entry) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
2 changes: 1 addition & 1 deletion ext/mysqli/mysqli_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static int driver_report_write(mysqli_object *obj, zval *value TSRMLS_DC)
{
MyG(report_mode) = Z_LVAL_P(value);
/*FIXME*/
zend_replace_error_handling(MyG(report_mode) & MYSQLI_REPORT_STRICT ? EH_THROW : EH_NORMAL, NULL, NULL TSRMLS_CC);
/* zend_replace_error_handling(MyG(report_mode) & MYSQLI_REPORT_STRICT ? EH_THROW : EH_NORMAL, NULL, NULL TSRMLS_CC); */
return SUCCESS;
}
/* }}} */
Expand Down
1 change: 1 addition & 0 deletions ext/simplexml/simplexml.c
Original file line number Diff line number Diff line change
Expand Up @@ -2182,6 +2182,7 @@ SXE_METHOD(__construct)

zend_replace_error_handling(EH_THROW, NULL, &error_handling TSRMLS_CC);
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lbsb", &data, &data_len, &options, &is_url, &ns, &ns_len, &isprefix) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand Down
6 changes: 5 additions & 1 deletion ext/spl/spl_array.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,16 +1010,18 @@ SPL_METHOD(Array, __construct)
zval **array;
long ar_flags = 0;
zend_class_entry *ce_get_iterator = spl_ce_Iterator;
zend_error_handling error_handling;

if (ZEND_NUM_ARGS() == 0) {
return; /* nothing to do */
}

zend_replace_error_handling(EH_THROW, spl_ce_InvalidArgumentException, NULL TSRMLS_CC);
zend_replace_error_handling(EH_THROW, spl_ce_InvalidArgumentException, &error_handling TSRMLS_CC);

intern = (spl_array_object*)zend_object_store_get_object(object TSRMLS_CC);

if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|lC", &array, &ar_flags, &ce_get_iterator) == FAILURE) {
zend_restore_error_handling(&error_handling TSRMLS_CC);
return;
}

Expand All @@ -1031,6 +1033,8 @@ SPL_METHOD(Array, __construct)

spl_array_set_array(object, intern, array, ar_flags, ZEND_NUM_ARGS() == 1 TSRMLS_CC);

zend_restore_error_handling(&error_handling TSRMLS_CC);

}
/* }}} */

Expand Down
Loading

0 comments on commit 3919b16

Please sign in to comment.