Skip to content

Commit 75742d5

Browse files
committed
Exceptions triggered by undefined variable should be handled before FATAL error
this is a enhancement of the fix for bug #64135
1 parent cddc9f5 commit 75742d5

File tree

4 files changed

+222
-5
lines changed

4 files changed

+222
-5
lines changed

Zend/tests/bug51394.phpt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,8 @@ function eh()
1313
set_error_handler("eh");
1414
$a = $empty($b);
1515
--EXPECTF--
16-
Warning: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:4
16+
Fatal error: Uncaught exception 'Exception' with message 'error!' in %sbug51394.php:%d
1717
Stack trace:
18-
#0 %sbug51394.php(9): eh(8, 'Undefined varia...', '%s', 9, Array)
18+
#0 %sbug51394.php(%d): eh(8, 'Undefined varia%s', '%s', %d, Array)
1919
#1 {main}
20-
thrown in %sbug51394.php on line 4
21-
22-
Fatal error: Function name must be a string in %sbug51394.php on line 9
20+
thrown in %sbug51394.php on line %d
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
--TEST--
2+
Exceptions before fatal error
3+
--FILE--
4+
<?php
5+
function exception_error_handler($code, $msg) {
6+
throw new Exception($msg);
7+
}
8+
9+
set_error_handler("exception_error_handler");
10+
11+
try {
12+
$foo->a();
13+
} catch(Exception $e) {
14+
var_dump($e->getMessage());
15+
}
16+
17+
try {
18+
new $foo();
19+
} catch(Exception $e) {
20+
var_dump($e->getMessage());
21+
}
22+
23+
try {
24+
throw $foo;
25+
} catch(Exception $e) {
26+
var_dump($e->getMessage());
27+
}
28+
29+
try {
30+
$foo();
31+
} catch(Exception $e) {
32+
var_dump($e->getMessage());
33+
}
34+
35+
try {
36+
$foo::b();
37+
} catch(Exception $e) {
38+
var_dump($e->getMessage());
39+
}
40+
41+
42+
try {
43+
$b = clone $foo;
44+
} catch(Exception $e) {
45+
var_dump($e->getMessage());
46+
}
47+
48+
class b {
49+
}
50+
51+
try {
52+
b::$foo();
53+
} catch(Exception $e) {
54+
var_dump($e->getMessage());
55+
}
56+
?>
57+
--EXPECT--
58+
string(23) "Undefined variable: foo"
59+
string(23) "Undefined variable: foo"
60+
string(23) "Undefined variable: foo"
61+
string(23) "Undefined variable: foo"
62+
string(23) "Undefined variable: foo"
63+
string(23) "Undefined variable: foo"
64+
string(23) "Undefined variable: foo"

Zend/zend_vm_def.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2405,6 +2405,9 @@ ZEND_VM_HANDLER(109, ZEND_FETCH_CLASS, ANY, CONST|TMP|VAR|UNUSED|CV)
24052405
} else if (Z_TYPE_P(class_name) == IS_STRING) {
24062406
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);
24072407
} else {
2408+
if (UNEXPECTED(EG(exception) != NULL)) {
2409+
HANDLE_EXCEPTION();
2410+
}
24082411
zend_error_noreturn(E_ERROR, "Class name must be a valid object or a string");
24092412
}
24102413

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

24302433
if (OP2_TYPE != IS_CONST &&
24312434
UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2435+
if (UNEXPECTED(EG(exception) != NULL)) {
2436+
HANDLE_EXCEPTION();
2437+
}
24322438
zend_error_noreturn(E_ERROR, "Method name must be a string");
24332439
}
24342440

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

25462552
if (UNEXPECTED(Z_TYPE_P(function_name) != IS_STRING)) {
2553+
if (UNEXPECTED(EG(exception) != NULL)) {
2554+
HANDLE_EXCEPTION();
2555+
}
25472556
zend_error_noreturn(E_ERROR, "Function name must be a string");
25482557
} else {
25492558
function_name_strval = Z_STRVAL_P(function_name);
@@ -2747,6 +2756,9 @@ ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST|TMP|VAR|CV)
27472756
CHECK_EXCEPTION();
27482757
ZEND_VM_NEXT_OPCODE();
27492758
} else {
2759+
if (UNEXPECTED(EG(exception) != NULL)) {
2760+
HANDLE_EXCEPTION();
2761+
}
27502762
zend_error_noreturn(E_ERROR, "Function name must be a string");
27512763
ZEND_VM_NEXT_OPCODE(); /* Never reached */
27522764
}
@@ -2959,8 +2971,12 @@ ZEND_VM_HANDLER(108, ZEND_THROW, CONST|TMP|VAR|CV, ANY)
29592971
value = GET_OP1_ZVAL_PTR(BP_VAR_R);
29602972

29612973
if (OP1_TYPE == IS_CONST || UNEXPECTED(Z_TYPE_P(value) != IS_OBJECT)) {
2974+
if (UNEXPECTED(EG(exception) != NULL)) {
2975+
HANDLE_EXCEPTION();
2976+
}
29622977
zend_error_noreturn(E_ERROR, "Can only throw objects");
29632978
}
2979+
29642980
zend_exception_save(TSRMLS_C);
29652981
/* Not sure if a complete copy is what we want here */
29662982
ALLOC_ZVAL(exception);
@@ -3423,6 +3439,9 @@ ZEND_VM_HANDLER(110, ZEND_CLONE, CONST|TMP|VAR|UNUSED|CV, ANY)
34233439

34243440
if (OP1_TYPE == IS_CONST ||
34253441
UNEXPECTED(Z_TYPE_P(obj) != IS_OBJECT)) {
3442+
if (UNEXPECTED(EG(exception) != NULL)) {
3443+
HANDLE_EXCEPTION();
3444+
}
34263445
zend_error_noreturn(E_ERROR, "__clone method called on non-object");
34273446
}
34283447

0 commit comments

Comments
 (0)