Skip to content

Commit 6dd85f8

Browse files
committedFeb 22, 2021
Fixed bug #80781
zend_find_array_dim_slow() may throw, make sure to handle this. This backports the code we already use for this on PHP-8.0, and also backports an exception check that makes this easier to catch.
1 parent 84b6152 commit 6dd85f8

File tree

5 files changed

+77
-0
lines changed

5 files changed

+77
-0
lines changed
 

‎NEWS

+4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? 2021, php 7.4.17
44

5+
- Core:
6+
. Fixed bug #80781 (Error handler that throws ErrorException infinite loop).
7+
(Nikita)
8+
59
- Intl:
610
. Fixed bug #80763 (msgfmt_format() does not accept DateTime references).
711
(cmb)

‎Zend/tests/bug80781.phpt

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
--TEST--
2+
Bug #80781: Error handler that throws ErrorException infinite loop
3+
--FILE--
4+
<?php
5+
6+
function handle(int $severity, string $message, string $file, int $line): bool {
7+
if((error_reporting() & $severity) !== 0) {
8+
throw new \ErrorException($message, 0, $severity, $file, $line);
9+
}
10+
11+
return true; // stfu operator
12+
}
13+
14+
set_error_handler('handle');
15+
16+
function getPlugin(string $plugin) : bool{
17+
return false;
18+
}
19+
20+
$data = [];
21+
$array = [];
22+
if (isset($array[$data]) or getPlugin($data)) {
23+
24+
}
25+
26+
?>
27+
--EXPECTF--
28+
Fatal error: Uncaught ErrorException: Illegal offset type in isset or empty in %s:%d
29+
Stack trace:
30+
#0 %s(%d): handle(2, 'Illegal offset ...', %s, %d, Array)
31+
#1 {main}
32+
thrown in %s on line %d

‎Zend/zend_execute.c

+1
Original file line numberDiff line numberDiff line change
@@ -4555,6 +4555,7 @@ static zend_always_inline zend_execute_data *_zend_vm_stack_push_call_frame(uint
45554555
if (check_exception) { \
45564556
OPLINE = EX(opline) + (skip); \
45574557
} else { \
4558+
ZEND_ASSERT(!EG(exception)); \
45584559
OPLINE = opline + (skip); \
45594560
} \
45604561
ZEND_VM_CONTINUE()

‎Zend/zend_vm_def.h

+4
Original file line numberDiff line numberDiff line change
@@ -6937,6 +6937,10 @@ ZEND_VM_C_LABEL(num_index_prop):
69376937
ZEND_VM_C_GOTO(isset_again);
69386938
} else {
69396939
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
6940+
if (UNEXPECTED(EG(exception))) {
6941+
result = 0;
6942+
ZEND_VM_C_GOTO(isset_dim_obj_exit);
6943+
}
69406944
}
69416945

69426946
if (!(opline->extended_value & ZEND_ISEMPTY)) {

‎Zend/zend_vm_execute.h

+36
Original file line numberDiff line numberDiff line change
@@ -6302,6 +6302,10 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM
63026302
goto isset_again;
63036303
} else {
63046304
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
6305+
if (UNEXPECTED(EG(exception))) {
6306+
result = 0;
6307+
goto isset_dim_obj_exit;
6308+
}
63056309
}
63066310

63076311
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -8496,6 +8500,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
84968500
goto isset_again;
84978501
} else {
84988502
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
8503+
if (UNEXPECTED(EG(exception))) {
8504+
result = 0;
8505+
goto isset_dim_obj_exit;
8506+
}
84998507
}
85008508

85018509
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -10949,6 +10957,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CON
1094910957
goto isset_again;
1095010958
} else {
1095110959
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
10960+
if (UNEXPECTED(EG(exception))) {
10961+
result = 0;
10962+
goto isset_dim_obj_exit;
10963+
}
1095210964
}
1095310965

1095410966
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -14985,6 +14997,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
1498514997
goto isset_again;
1498614998
} else {
1498714999
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
15000+
if (UNEXPECTED(EG(exception))) {
15001+
result = 0;
15002+
goto isset_dim_obj_exit;
15003+
}
1498815004
}
1498915005

1499015006
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -16402,6 +16418,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
1640216418
goto isset_again;
1640316419
} else {
1640416420
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
16421+
if (UNEXPECTED(EG(exception))) {
16422+
result = 0;
16423+
goto isset_dim_obj_exit;
16424+
}
1640516425
}
1640616426

1640716427
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -17689,6 +17709,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_TMP
1768917709
goto isset_again;
1769017710
} else {
1769117711
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
17712+
if (UNEXPECTED(EG(exception))) {
17713+
result = 0;
17714+
goto isset_dim_obj_exit;
17715+
}
1769217716
}
1769317717

1769417718
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -41505,6 +41529,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
4150541529
goto isset_again;
4150641530
} else {
4150741531
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
41532+
if (UNEXPECTED(EG(exception))) {
41533+
result = 0;
41534+
goto isset_dim_obj_exit;
41535+
}
4150841536
}
4150941537

4151041538
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -44950,6 +44978,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
4495044978
goto isset_again;
4495144979
} else {
4495244980
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
44981+
if (UNEXPECTED(EG(exception))) {
44982+
result = 0;
44983+
goto isset_dim_obj_exit;
44984+
}
4495344985
}
4495444986

4495544987
if (!(opline->extended_value & ZEND_ISEMPTY)) {
@@ -50123,6 +50155,10 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ISSET_ISEMPTY_DIM_OBJ_SPEC_CV_
5012350155
goto isset_again;
5012450156
} else {
5012550157
value = zend_find_array_dim_slow(ht, offset EXECUTE_DATA_CC);
50158+
if (UNEXPECTED(EG(exception))) {
50159+
result = 0;
50160+
goto isset_dim_obj_exit;
50161+
}
5012650162
}
5012750163

5012850164
if (!(opline->extended_value & ZEND_ISEMPTY)) {

0 commit comments

Comments
 (0)