Skip to content

Commit

Permalink
Exceptions triggered by undefined variable should be handled before F…
Browse files Browse the repository at this point in the history
…ATAL error

this is a enhancement of the fix for bug #64135
  • Loading branch information
laruence committed Feb 16, 2013
1 parent cddc9f5 commit 75742d5
Show file tree
Hide file tree
Showing 4 changed files with 222 additions and 5 deletions.
8 changes: 3 additions & 5 deletions Zend/tests/bug51394.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ function eh()
set_error_handler("eh");
$a = $empty($b);
--EXPECTF--
Warning: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:4
Fatal error: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:%d
Stack trace:
#0 %sbug51394.php(9): eh(8, 'Undefined varia...', '%s', 9, Array)
#0 %sbug51394.php(%d): eh(8, 'Undefined varia%s', '%s', %d, Array)
#1 {main}
thrown in %sbug51394.php on line 4

Fatal error: Function name must be a string in %sbug51394.php on line 9
thrown in %sbug51394.php on line %d
64 changes: 64 additions & 0 deletions Zend/tests/exception_before_fatal.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
--TEST--
Exceptions before fatal error
--FILE--
<?php
function exception_error_handler($code, $msg) {
throw new Exception($msg);
}

set_error_handler("exception_error_handler");

try {
$foo->a();
} catch(Exception $e) {
var_dump($e->getMessage());
}

try {
new $foo();
} catch(Exception $e) {
var_dump($e->getMessage());
}

try {
throw $foo;
} catch(Exception $e) {
var_dump($e->getMessage());
}

try {
$foo();
} catch(Exception $e) {
var_dump($e->getMessage());
}

try {
$foo::b();
} catch(Exception $e) {
var_dump($e->getMessage());
}


try {
$b = clone $foo;
} catch(Exception $e) {
var_dump($e->getMessage());
}

class b {
}

try {
b::$foo();
} catch(Exception $e) {
var_dump($e->getMessage());
}
?>
--EXPECT--
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
string(23) "Undefined variable: foo"
19 changes: 19 additions & 0 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -2405,6 +2405,9 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
} else if (Z_TYPE_P(class_name) == IS_STRING) {
EX_T(opline->result.var).class_entry = zend_fetch_class(Z_STRVAL_P(class_name), Z_STRLEN_P(class_name), opline->extended_value TSRMLS_CC);
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
}

Expand All @@ -2429,6 +2432,9 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV)

if (OP2_TYPE != IS_CONST &&
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Method name must be a string");
}

Expand Down Expand Up @@ -2544,6 +2550,9 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMP|VAR|UNUS
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);

if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
} else {
function_name_strval = Z_STRVAL_P(function_name);
Expand Down Expand Up @@ -2747,6 +2756,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
CHECK_EXCEPTION();
ZEND_VM_NEXT_OPCODE();
} else {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Function name must be a string");
ZEND_VM_NEXT_OPCODE(); /* Never reached */
}
Expand Down Expand Up @@ -2959,8 +2971,12 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
value = GET_OP1_ZVAL_PTR(BP_VAR_R);

if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "Can only throw objects");
}

zend_exception_save(TSRMLS_C);
/* Not sure if a complete copy is what we want here */
ALLOC_ZVAL(exception);
Expand Down Expand Up @@ -3423,6 +3439,9 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)

if (OP1_TYPE == IS_CONST ||
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
if (UNEXPECTED(EG(exception) != NULL)) {
HANDLE_EXCEPTION();
}
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
}

Expand Down
Loading

0 comments on commit 75742d5

Please sign in to comment.