From afe98b7829d50806559acac9b530acb8283c3bf4 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Thu, 7 Feb 2013 16:07:05 +0400 Subject: [PATCH 1/5] Disabled external entities loading --- ext/soap/php_xml.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 65abed171a3..a69d071164f 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -92,6 +92,7 @@ xmlDocPtr soap_xmlParseFile(const char *filename TSRMLS_DC) PG(allow_url_fopen) = old_allow_url_fopen; if (ctxt) { ctxt->keepBlanks = 0; + ctxt->options -= XML_PARSE_DTDLOAD; ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ctxt->sax->comment = soap_Comment; ctxt->sax->warning = NULL; @@ -133,6 +134,7 @@ xmlDocPtr soap_xmlParseMemory(const void *buf, size_t buf_size) */ ctxt = xmlCreateMemoryParserCtxt(buf, buf_size); if (ctxt) { + ctxt->options -= XML_PARSE_DTDLOAD; ctxt->sax->ignorableWhitespace = soap_ignorableWhitespace; ctxt->sax->comment = soap_Comment; ctxt->sax->warning = NULL; From 9fb0dba4be197b677b6ff7df23a110698d12530b Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Thu, 7 Feb 2013 16:05:27 +0100 Subject: [PATCH 2/5] Add support for commit and rollback options. Add support for explicitly starting a transaction - modes also available. Using the API makes the life of load balancer mysqlnd plugins easier/possible. --- ext/mysqlnd/mysqlnd.c | 139 ++++++++++++++++++++++++++++--- ext/mysqlnd/mysqlnd_enum_n_def.h | 12 +++ ext/mysqlnd/mysqlnd_structs.h | 9 ++ 3 files changed, 147 insertions(+), 13 deletions(-) diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 1bab6f5b7a0..d7ddcb594b6 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -2617,16 +2617,7 @@ MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit)(MYSQLND_CONN_DATA * conn, unsi static enum_func_status MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC) { - size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_commit); - enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_conn_data::tx_commit"); - - if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { - ret = conn->m->query(conn, "COMMIT", sizeof("COMMIT") - 1 TSRMLS_CC); - conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); - } - - DBG_RETURN(ret); + return conn->m->tx_commit_or_rollback(conn, TRUE, TRANS_COR_NO_OPT, NULL TSRMLS_CC); } /* }}} */ @@ -2635,12 +2626,70 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC) static enum_func_status MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC) { - size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_rollback); + return conn->m->tx_commit_or_rollback(conn, FALSE, TRANS_COR_NO_OPT, NULL TSRMLS_CC); +} +/* }}} */ + + +/* {{{ mysqlnd_tx_cor_options_to_string */ +static void +MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string)(const MYSQLND_CONN_DATA * const conn, smart_str * str, const unsigned int mode TSRMLS_DC) +{ + if (mode & TRANS_COR_AND_CHAIN && !(mode & TRANS_COR_AND_NO_CHAIN)) { + if (str->len) { + smart_str_appendl(str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(str, "AND CHAIN", sizeof("AND CHAIN") - 1); + } else if (mode & TRANS_COR_AND_NO_CHAIN && !(mode & TRANS_COR_AND_CHAIN)) { + if (str->len) { + smart_str_appendl(str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(str, "AND NO CHAIN", sizeof("AND NO CHAIN") - 1); + } + + if (mode & TRANS_COR_RELEASE && !(mode & TRANS_COR_NO_RELEASE)) { + if (str->len) { + smart_str_appendl(str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(str, "RELEASE", sizeof("RELEASE") - 1); + } else if (mode & TRANS_COR_NO_RELEASE && !(mode & TRANS_COR_RELEASE)) { + if (str->len) { + smart_str_appendl(str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(str, "NO RELEASE", sizeof("NO RELEASE") - 1); + } + smart_str_0(str); +} +/* }}} */ + + +/* {{{ mysqlnd_conn_data::tx_commit_ex */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name TSRMLS_DC) +{ + size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_commit_or_rollback); enum_func_status ret = FAIL; - DBG_ENTER("mysqlnd_conn_data::tx_rollback"); + DBG_ENTER("mysqlnd_conn_data::tx_commit_or_rollback"); if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { - ret = conn->m->query(conn, "ROLLBACK", sizeof("ROLLBACK") - 1 TSRMLS_CC); + do { + smart_str tmp_str = {0, 0, 0}; + conn->m->tx_cor_options_to_string(conn, &tmp_str, flags TSRMLS_CC); + smart_str_0(&tmp_str); + + { + char * query; + unsigned int query_len = mnd_sprintf(&query, 0, (commit? "COMMIT %s":"ROLLBACK %s"), tmp_str.c? tmp_str.c:""); + smart_str_free(&tmp_str); + + if (!query) { + SET_OOM_ERROR(*conn->error_info); + break; + } + ret = conn->m->query(conn, query, query_len TSRMLS_CC); + mnd_sprintf_free(query); + } + } while (0); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); } @@ -2649,6 +2698,66 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_D /* }}} */ +/* {{{ mysqlnd_conn_data::tx_begin */ +static enum_func_status +MYSQLND_METHOD(mysqlnd_conn_data, tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned int mode, const char * const name TSRMLS_DC) +{ + size_t this_func = STRUCT_OFFSET(struct st_mysqlnd_conn_data_methods, tx_begin); + enum_func_status ret = FAIL; + DBG_ENTER("mysqlnd_conn_data::tx_begin"); + + if (PASS == conn->m->local_tx_start(conn, this_func TSRMLS_CC)) { + do { + smart_str tmp_str = {0, 0, 0}; + if (mode & TRANS_START_WITH_CONSISTENT_SNAPSHOT) { + if (tmp_str.len) { + smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(&tmp_str, "WITH CONSISTENT SNAPSHOT", sizeof("WITH CONSISTENT SNAPSHOT") - 1); + } + if (mode & TRANS_START_READ_WRITE) { + if (tmp_str.len) { + smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(&tmp_str, "READ WRITE", sizeof("READ WRITE") - 1); + } + if (mode & TRANS_START_READ_ONLY) { + if (tmp_str.len) { + smart_str_appendl(&tmp_str, ", ", sizeof(", ") - 1); + } + smart_str_appendl(&tmp_str, "READ ONLY", sizeof("READ ONLY") - 1); + } + smart_str_0(&tmp_str); + + { + char * commented_name = NULL; + unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0; + char * query; + unsigned int query_len = mnd_sprintf(&query, 0, "START TRANSACTION%s %s", commented_name? commented_name:"", tmp_str.c? tmp_str.c:""); + smart_str_free(&tmp_str); + + if (!query) { + SET_OOM_ERROR(*conn->error_info); + break; + } + ret = conn->m->query(conn, query, query_len TSRMLS_CC); + mnd_sprintf_free(query); + if (commented_name) { + mnd_sprintf_free(commented_name); + } + } + } while (0); + conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); + } + + DBG_RETURN(ret); +} +/* }}} */ + + +typedef enum_func_status (*func_mysqlnd_conn_data__)(MYSQLND_CONN_DATA * conn, const unsigned int flags, const char * const name TSRMLS_DC); + + /* {{{ mysqlnd_conn_data::local_tx_start */ static enum_func_status MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start)(MYSQLND_CONN_DATA * conn, size_t this_func TSRMLS_DC) @@ -2763,6 +2872,10 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn_data) MYSQLND_METHOD(mysqlnd_conn_data, set_autocommit), MYSQLND_METHOD(mysqlnd_conn_data, tx_commit), MYSQLND_METHOD(mysqlnd_conn_data, tx_rollback), + MYSQLND_METHOD(mysqlnd_conn_data, tx_begin), + MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback), + MYSQLND_METHOD(mysqlnd_conn_data, tx_cor_options_to_string), + MYSQLND_METHOD(mysqlnd_conn_data, local_tx_start), MYSQLND_METHOD(mysqlnd_conn_data, local_tx_end), MYSQLND_METHOD(mysqlnd_conn_data, execute_init_commands), diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index cf5b02728ba..1d645a8d75c 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -108,6 +108,18 @@ #define MYSQLND_NET_FLAG_USE_COMPRESSION 1 + +#define TRANS_START_NO_OPT 0 +#define TRANS_START_WITH_CONSISTENT_SNAPSHOT 1 +#define TRANS_START_READ_WRITE 2 +#define TRANS_START_READ_ONLY 4 + +#define TRANS_COR_NO_OPT 0 +#define TRANS_COR_AND_CHAIN 1 +#define TRANS_COR_AND_NO_CHAIN 2 +#define TRANS_COR_RELEASE 4 +#define TRANS_COR_NO_RELEASE 8 + typedef enum mysqlnd_extension { MYSQLND_MYSQL = 0, diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index b88004a9f11..7d22dafb8fc 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -23,6 +23,8 @@ #ifndef MYSQLND_STRUCTS_H #define MYSQLND_STRUCTS_H +#include "ext/standard/php_smart_str.h" + #define MYSQLND_TYPEDEFED_METHODS #define MYSQLND_CLASS_METHOD_TABLE_NAME(class) mysqlnd_##class##_methods @@ -31,6 +33,7 @@ #define MYSQLND_CLASS_METHODS_START(class) MYSQLND_CLASS_METHOD_TABLE_NAME_FORWARD(class) = { #define MYSQLND_CLASS_METHODS_END } + typedef struct st_mysqlnd_memory_pool MYSQLND_MEMORY_POOL; typedef struct st_mysqlnd_memory_pool_chunk MYSQLND_MEMORY_POOL_CHUNK; typedef struct st_mysqlnd_memory_pool_chunk_llist MYSQLND_MEMORY_POOL_CHUNK_LLIST; @@ -480,6 +483,9 @@ typedef MYSQLND_RES * (*func_mysqlnd_conn_data__result_init)(unsigned int fiel typedef enum_func_status (*func_mysqlnd_conn_data__set_autocommit)(MYSQLND_CONN_DATA * conn, unsigned int mode TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn_data__tx_commit)(MYSQLND_CONN_DATA * conn TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn_data__tx_rollback)(MYSQLND_CONN_DATA * conn TSRMLS_DC); +typedef enum_func_status (*func_mysqlnd_conn_data__tx_begin)(MYSQLND_CONN_DATA * conn, const unsigned int mode, const char * const name TSRMLS_DC); +typedef enum_func_status (*func_mysqlnd_conn_data__tx_commit_or_rollback)(MYSQLND_CONN_DATA * conn, const zend_bool commit, const unsigned int flags, const char * const name TSRMLS_DC); +typedef void (*func_mysqlnd_conn_data__tx_cor_options_to_string)(const MYSQLND_CONN_DATA * const conn, smart_str * tmp_str, const unsigned int mode TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_start)(MYSQLND_CONN_DATA * conn, size_t this_func TSRMLS_DC); typedef enum_func_status (*func_mysqlnd_conn_data__local_tx_end)(MYSQLND_CONN_DATA * conn, size_t this_func, enum_func_status status TSRMLS_DC); @@ -566,6 +572,9 @@ struct st_mysqlnd_conn_data_methods func_mysqlnd_conn_data__set_autocommit set_autocommit; func_mysqlnd_conn_data__tx_commit tx_commit; func_mysqlnd_conn_data__tx_rollback tx_rollback; + func_mysqlnd_conn_data__tx_begin tx_begin; + func_mysqlnd_conn_data__tx_commit_or_rollback tx_commit_or_rollback; + func_mysqlnd_conn_data__tx_cor_options_to_string tx_cor_options_to_string; func_mysqlnd_conn_data__local_tx_start local_tx_start; func_mysqlnd_conn_data__local_tx_end local_tx_end; From 49e3d91ad91bd3b65e2142641f80de0401396b85 Mon Sep 17 00:00:00 2001 From: Andrey Hristov Date: Thu, 7 Feb 2013 16:24:08 +0100 Subject: [PATCH 3/5] Add the name in a comment at commit/rollback, if provided --- ext/mysqlnd/mysqlnd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index d7ddcb594b6..0e47def6d13 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -2678,8 +2678,11 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * con smart_str_0(&tmp_str); { + char * commented_name = NULL; + unsigned int commented_name_len = name? mnd_sprintf(&commented_name, 0, " /*%s*/", name):0; char * query; - unsigned int query_len = mnd_sprintf(&query, 0, (commit? "COMMIT %s":"ROLLBACK %s"), tmp_str.c? tmp_str.c:""); + unsigned int query_len = mnd_sprintf(&query, 0, (commit? "COMMIT%s %s":"ROLLBACK%s %s"), + commented_name? commented_name:"", tmp_str.c? tmp_str.c:""); smart_str_free(&tmp_str); if (!query) { @@ -2688,6 +2691,9 @@ MYSQLND_METHOD(mysqlnd_conn_data, tx_commit_or_rollback)(MYSQLND_CONN_DATA * con } ret = conn->m->query(conn, query, query_len TSRMLS_CC); mnd_sprintf_free(query); + if (commented_name) { + mnd_sprintf_free(commented_name); + } } } while (0); conn->m->local_tx_end(conn, this_func, ret TSRMLS_CC); From 290509755ac4a3279b2b31b899aa9f2dd780f5f4 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 7 Feb 2013 23:44:46 +0800 Subject: [PATCH 4/5] Fixed bug #64135 (Exceptions from set_error_handler are not always propagated) --- NEWS | 6 ++-- Zend/tests/bug61767.phpt | 12 ++++---- Zend/zend_vm_def.h | 4 +++ Zend/zend_vm_execute.h | 64 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 77 insertions(+), 9 deletions(-) diff --git a/NEWS b/NEWS index c343f4315a5..3bb6acef8a5 100644 --- a/NEWS +++ b/NEWS @@ -3,11 +3,13 @@ PHP NEWS ?? ??? 201?, PHP 5.5.0 Beta 1 - Core: + . Fixed bug #64135 (Exceptions from set_error_handler are not always + propagated). (Laruence) + . Fixed bug #63830 (Segfault on undefined function call in nested generator). + (Nikita Popov) . Fixed bug #60833 (self, parent, static behave inconsistently case-sensitive). (Stas, mario at include-once dot org) . Implemented FR #60524 (specify temp dir by php.ini). (ALeX Kazik). - . Fixed bug #63830 (Segfault on undefined function call in nested generator). - (Nikita Popov) - CLI server: . Fixed bug #64128 (buit-in web server is broken on ppc64). (Remi) diff --git a/Zend/tests/bug61767.phpt b/Zend/tests/bug61767.phpt index 5270872e5d8..9bd9c907bdc 100644 --- a/Zend/tests/bug61767.phpt +++ b/Zend/tests/bug61767.phpt @@ -17,18 +17,16 @@ $undefined->foo(); --EXPECTF-- Error handler called (Undefined variable: undefined) -Warning: Uncaught exception 'ErrorException' with message 'Undefined variable: undefined' in %sbug61767.php:13 +Fatal error: Uncaught exception 'ErrorException' with message 'Undefined variable: undefined' in %sbug61767.php:%d Stack trace: -#0 %sbug61767.php(13): {closure}(8, 'Undefined varia...', '%s', 13, Array) +#0 %sbug61767.php(%d): {closure}(%s, 'Undefined varia...', '%s', %d, Array) #1 {main} - thrown in %sbug61767.php on line 13 - -Fatal error: Call to a member function foo() on a non-object in %sbug61767.php on line 13 + thrown in %sbug61767.php on line %d Shutting down Array ( [type] => 1 - [message] => Call to a member function foo() on a non-object + [message] => %a [file] => %sbug61767.php - [line] => 13 + [line] => %d ) diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4dd544e5780..cbd3810a210 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2462,6 +2462,10 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + FREE_OP2(); + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 25ac1ea89e7..7b874decef2 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -8947,6 +8947,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -9801,6 +9805,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_dtor(free_op2.var); + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -10660,6 +10668,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -12094,6 +12106,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -15319,6 +15335,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -17660,6 +17680,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_dtor(free_op2.var); + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -19966,6 +19990,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -23407,6 +23435,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -25033,6 +25065,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -26441,6 +26477,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_dtor(free_op2.var); + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -27755,6 +27795,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -29490,6 +29534,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -32718,6 +32766,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -34831,6 +34883,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + zval_dtor(free_op2.var); + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -37003,6 +37059,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + if (free_op2.var) {zval_ptr_dtor(&free_op2.var);}; + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } @@ -40167,6 +40227,10 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H } } } else { + if (UNEXPECTED(EG(exception) != NULL)) { + + HANDLE_EXCEPTION(); + } zend_error_noreturn(E_ERROR, "Call to a member function %s() on a non-object", function_name_strval); } From 7948eea6f9833d4dd97cd34af37465af9efcec78 Mon Sep 17 00:00:00 2001 From: Xinchen Hui Date: Thu, 7 Feb 2013 23:49:35 +0800 Subject: [PATCH 5/5] Forgot test script --- Zend/tests/bug64135.phpt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Zend/tests/bug64135.phpt diff --git a/Zend/tests/bug64135.phpt b/Zend/tests/bug64135.phpt new file mode 100644 index 00000000000..1c7b1500a2b --- /dev/null +++ b/Zend/tests/bug64135.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #64135 (Exceptions from set_error_handler are not always propagated) +--FILE-- +undefined(); +} catch(Exception $e) { + echo "Exception is thrown"; +} +--EXPECT-- +Exception is thrown