diff options
author | Bob Weinand <bobwei9@hotmail.com> | 2015-04-22 01:07:52 +0200 |
---|---|---|
committer | Bob Weinand <bobwei9@hotmail.com> | 2015-04-22 01:08:08 +0200 |
commit | e09a0bfc9e849b558fb03be33ac463ef3288305b (patch) | |
tree | 5fc1c271e135dfe9a49e819760de6c424b67b6af | |
parent | 73d31d44e8b59804077b4f6451e06caf69166a6b (diff) | |
download | php-git-e09a0bfc9e849b558fb03be33ac463ef3288305b.tar.gz |
Also consider specific catches when checking for uncaught
-rw-r--r-- | sapi/phpdbg/phpdbg_prompt.c | 6 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_utils.c | 36 | ||||
-rw-r--r-- | sapi/phpdbg/phpdbg_utils.h | 2 |
3 files changed, 33 insertions, 11 deletions
diff --git a/sapi/phpdbg/phpdbg_prompt.c b/sapi/phpdbg/phpdbg_prompt.c index 11af5bc790..e2978fb5c7 100644 --- a/sapi/phpdbg/phpdbg_prompt.c +++ b/sapi/phpdbg/phpdbg_prompt.c @@ -1446,12 +1446,12 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */ continue; } - if (phpdbg_check_caught_ex(prev_ex)) { + if (phpdbg_check_caught_ex(prev_ex, exception)) { goto ex_is_caught; } } while ((prev_ex = prev_ex->prev_execute_data)); - PHPDBG_G(handled_exception) = EG(exception); + PHPDBG_G(handled_exception) = exception; phpdbg_error("exception", "name=\"%s\"", "Uncaught exception %s", exception->ce->name->val); DO_INTERACTIVE(1); } @@ -1474,7 +1474,7 @@ ex_is_caught: goto next; } -#define INDEX_EXISTS_CHECK (zend_hash_index_exists(&PHPDBG_G(seek), address) || (EG(exception) && phpdbg_check_caught_ex(execute_data) == 0)) +#define INDEX_EXISTS_CHECK (zend_hash_index_exists(&PHPDBG_G(seek), address) || (exception && phpdbg_check_caught_ex(execute_data, exception) == 0)) /* run to next line */ if (PHPDBG_G(flags) & PHPDBG_IN_UNTIL) { diff --git a/sapi/phpdbg/phpdbg_utils.c b/sapi/phpdbg/phpdbg_utils.c index fce042a225..9d63fcf727 100644 --- a/sapi/phpdbg/phpdbg_utils.c +++ b/sapi/phpdbg/phpdbg_utils.c @@ -713,24 +713,46 @@ head_done: } phpdbg_end_try_access(); } -PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *ex) { +PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zend_object *exception) { const zend_op *op; + zend_op *cur; uint32_t op_num, i; - zend_op_array *op_array = &ex->func->op_array; + zend_op_array *op_array = &execute_data->func->op_array; - if (ex->opline >= EG(exception_op) && ex->opline < EG(exception_op) + 3) { + if (execute_data->opline >= EG(exception_op) && execute_data->opline < EG(exception_op) + 3) { op = EG(opline_before_exception); } else { - op = ex->opline; + op = execute_data->opline; } op_num = op - op_array->opcodes; for (i = 0; i < op_array->last_try_catch && op_array->try_catch_array[i].try_op < op_num; i++) { - if (op_num <= op_array->try_catch_array[i].catch_op || op_num <= op_array->try_catch_array[i].finally_op) { - return 1; + uint32_t catch = op_array->try_catch_array[i].catch_op, finally = op_array->try_catch_array[i].finally_op; + if (op_num <= catch || op_num <= finally) { + if (finally && finally < catch) { + return 0; + } + + do { + zend_class_entry *ce; + cur = &op_array->opcodes[catch]; + + if (!(ce = CACHED_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(cur->op1))))) { + ce = zend_fetch_class_by_name(Z_STR_P(EX_CONSTANT(cur->op1)), EX_CONSTANT(cur->op1) + 1, ZEND_FETCH_CLASS_NO_AUTOLOAD); + CACHE_PTR(Z_CACHE_SLOT_P(EX_CONSTANT(cur->op1)), ce); + } + + if (ce == exception->ce || (ce && instanceof_function(exception->ce, ce))) { + return 1; + } + + catch = cur->extended_value; + } while (!cur->result.num); + + return 0; } } - return 0; + return op->opcode == ZEND_CATCH; } diff --git a/sapi/phpdbg/phpdbg_utils.h b/sapi/phpdbg/phpdbg_utils.h index 5ed2353987..dcf713e05b 100644 --- a/sapi/phpdbg/phpdbg_utils.h +++ b/sapi/phpdbg/phpdbg_utils.h @@ -94,7 +94,7 @@ int phpdbg_is_auto_global(char *name, int len); PHPDBG_API void phpdbg_xml_var_dump(zval *zv); -PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *ex); +PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *ex, zend_object *exception); #ifdef ZTS #define PHPDBG_OUTPUT_BACKUP_DEFINES() \ |