Skip to content

Commit 75a3de0

Browse files
committed
Fix misbehaviors with uncaught exceptions and finally or eval
1 parent 4dc0546 commit 75a3de0

File tree

2 files changed

+26
-23
lines changed

2 files changed

+26
-23
lines changed

sapi/phpdbg/phpdbg_prompt.c

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,7 @@ PHPDBG_COMMAND(run) /* {{{ */
659659
char **argv = emalloc(5 * sizeof(char *));
660660
int argc = 0;
661661
int i;
662+
/* TODO allow proper escaping with \, "" and '' here */
662663
char *argv_str = strtok(param->str, " ");
663664

664665
while (argv_str) {
@@ -767,15 +768,19 @@ PHPDBG_COMMAND(ev) /* {{{ */
767768
PHPDBG_G(flags) |= PHPDBG_IN_EVAL;
768769
zend_try {
769770
if (zend_eval_stringl(param->str, param->len, &retval, "eval()'d code") == SUCCESS) {
770-
phpdbg_xml("<eval %r>");
771-
if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
772-
zval *zvp = &retval;
773-
phpdbg_xml_var_dump(zvp);
771+
if (EG(exception)) {
772+
zend_exception_error(EG(exception), E_ERROR);
773+
} else {
774+
phpdbg_xml("<eval %r>");
775+
if (PHPDBG_G(flags) & PHPDBG_WRITE_XML) {
776+
zval *zvp = &retval;
777+
phpdbg_xml_var_dump(zvp);
778+
}
779+
zend_print_zval_r(&retval, 0);
780+
phpdbg_xml("</eval>");
781+
phpdbg_out("\n");
782+
zval_ptr_dtor(&retval);
774783
}
775-
zend_print_zval_r(&retval, 0);
776-
phpdbg_xml("</eval>");
777-
phpdbg_out("\n");
778-
zval_ptr_dtor(&retval);
779784
}
780785
} zend_catch {
781786
EG(current_execute_data) = original_execute_data;
@@ -784,6 +789,7 @@ PHPDBG_COMMAND(ev) /* {{{ */
784789
EG(vm_stack_end) = original_stack->end;
785790
EG(vm_stack) = original_stack;
786791
} zend_end_try();
792+
787793
PHPDBG_G(flags) &= ~PHPDBG_IN_EVAL;
788794

789795
/* switch stepping back on */
@@ -1391,18 +1397,17 @@ void phpdbg_clean(zend_bool full) /* {{{ */
13911397
\
13921398
switch (phpdbg_interactive(allow_async_unsafe)) { \
13931399
zval zv; \
1394-
default: \
1400+
case PHPDBG_LEAVE: \
1401+
case PHPDBG_FINISH: \
1402+
case PHPDBG_UNTIL: \
1403+
case PHPDBG_NEXT: \
13951404
if (exception) { \
13961405
Z_OBJ(zv) = exception; \
13971406
zend_throw_exception_internal(&zv); \
13981407
} \
13991408
/* fallthrough */ \
1400-
case PHPDBG_LEAVE: \
1401-
case PHPDBG_FINISH: \
1402-
case PHPDBG_UNTIL: \
1403-
case PHPDBG_NEXT:{ \
1409+
default: \
14041410
goto next; \
1405-
} \
14061411
} \
14071412
} while (0)
14081413

@@ -1431,7 +1436,7 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */
14311436
#endif
14321437

14331438
/* check for uncaught exceptions */
1434-
if (exception && PHPDBG_G(handled_exception) != exception) {
1439+
if (exception && PHPDBG_G(handled_exception) != exception && !(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) {
14351440
zend_execute_data *prev_ex = execute_data;
14361441
zval zv, rv;
14371442
zend_string *file, *msg;
@@ -1464,16 +1469,14 @@ void phpdbg_execute_ex(zend_execute_data *execute_data) /* {{{ */
14641469
}
14651470
ex_is_caught:
14661471

1467-
/* allow conditional breakpoints and
1468-
initialization to access the vm uninterrupted */
1469-
if ((PHPDBG_G(flags) & PHPDBG_IN_COND_BP) ||
1470-
(PHPDBG_G(flags) & PHPDBG_IS_INITIALIZING)) {
1472+
/* allow conditional breakpoints and initialization to access the vm uninterrupted */
1473+
if (PHPDBG_G(flags) & (PHPDBG_IN_COND_BP | PHPDBG_IS_INITIALIZING)) {
14711474
/* skip possible breakpoints */
14721475
goto next;
14731476
}
14741477

14751478
/* perform seek operation */
1476-
if (PHPDBG_G(flags) & PHPDBG_SEEK_MASK) {
1479+
if ((PHPDBG_G(flags) & PHPDBG_SEEK_MASK) && !(PHPDBG_G(flags) & PHPDBG_IN_EVAL)) {
14771480
/* current address */
14781481
zend_ulong address = (zend_ulong) execute_data->opline;
14791482

sapi/phpdbg/phpdbg_utils.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -728,11 +728,11 @@ PHPDBG_API zend_bool phpdbg_check_caught_ex(zend_execute_data *execute_data, zen
728728

729729
op_num = op - op_array->opcodes;
730730

731-
for (i = 0; i < op_array->last_try_catch && op_array->try_catch_array[i].try_op < op_num; i++) {
731+
for (i = 0; i < op_array->last_try_catch && op_array->try_catch_array[i].try_op <= op_num; i++) {
732732
uint32_t catch = op_array->try_catch_array[i].catch_op, finally = op_array->try_catch_array[i].finally_op;
733733
if (op_num <= catch || op_num <= finally) {
734-
if (finally && finally < catch) {
735-
return 0;
734+
if (finally) {
735+
return 1;
736736
}
737737

738738
do {

0 commit comments

Comments
 (0)