Skip to content

Commit 75b2973

Browse files
committed
Fix array clobbering by user error handler
Fixes oss-fuzz #42363
1 parent b16fc35 commit 75b2973

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

Zend/tests/falsetoarray_003.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Autovivification of false to array with data clobbering by error handler
3+
--FILE--
4+
<?php
5+
set_error_handler(function($code, $msg) {
6+
echo "Err: $msg\n";
7+
$GLOBALS['a']=9;
8+
});
9+
$a=[];
10+
($a[PHP_INT_MAX+1]);
11+
?>
12+
DONE
13+
--EXPECTF--
14+
Err: Implicit conversion from float %f to int loses precision
15+
Err: Undefined array key %i
16+
DONE

Zend/zend_vm_def.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9670,7 +9670,10 @@ ZEND_VM_C_LABEL(fetch_dim_r_index_array):
96709670
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
96719671
offset = Z_LVAL_P(dim);
96729672
} else {
9673-
offset = zval_get_long_ex(dim, /* is_strict */ true);
9673+
SAVE_OPLINE();
9674+
zend_fetch_dimension_address_read_R(container, dim, OP2_TYPE OPLINE_CC EXECUTE_DATA_CC);
9675+
FREE_OP1();
9676+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
96749677
}
96759678
ht = Z_ARRVAL_P(container);
96769679
ZEND_HASH_INDEX_FIND(ht, offset, value, ZEND_VM_C_LABEL(fetch_dim_r_index_undef));

Zend/zend_vm_execute.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8318,7 +8318,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
83188318
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
83198319
offset = Z_LVAL_P(dim);
83208320
} else {
8321-
offset = zval_get_long_ex(dim, /* is_strict */ true);
8321+
SAVE_OPLINE();
8322+
zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
8323+
8324+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
83228325
}
83238326
ht = Z_ARRVAL_P(container);
83248327
ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
@@ -16126,7 +16129,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
1612616129
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
1612716130
offset = Z_LVAL_P(dim);
1612816131
} else {
16129-
offset = zval_get_long_ex(dim, /* is_strict */ true);
16132+
SAVE_OPLINE();
16133+
zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
16134+
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
16135+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1613016136
}
1613116137
ht = Z_ARRVAL_P(container);
1613216138
ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
@@ -16178,7 +16184,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
1617816184
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
1617916185
offset = Z_LVAL_P(dim);
1618016186
} else {
16181-
offset = zval_get_long_ex(dim, /* is_strict */ true);
16187+
SAVE_OPLINE();
16188+
zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
16189+
zval_ptr_dtor_nogc(EX_VAR(opline->op1.var));
16190+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
1618216191
}
1618316192
ht = Z_ARRVAL_P(container);
1618416193
ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
@@ -42928,7 +42937,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
4292842937
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
4292942938
offset = Z_LVAL_P(dim);
4293042939
} else {
42931-
offset = zval_get_long_ex(dim, /* is_strict */ true);
42940+
SAVE_OPLINE();
42941+
zend_fetch_dimension_address_read_R(container, dim, IS_CONST OPLINE_CC EXECUTE_DATA_CC);
42942+
42943+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4293242944
}
4293342945
ht = Z_ARRVAL_P(container);
4293442946
ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);
@@ -42980,7 +42992,10 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_DIM_R_INDEX_
4298042992
if (EXPECTED(Z_TYPE_P(dim) == IS_LONG)) {
4298142993
offset = Z_LVAL_P(dim);
4298242994
} else {
42983-
offset = zval_get_long_ex(dim, /* is_strict */ true);
42995+
SAVE_OPLINE();
42996+
zend_fetch_dimension_address_read_R(container, dim, (IS_TMP_VAR|IS_VAR|IS_CV) OPLINE_CC EXECUTE_DATA_CC);
42997+
42998+
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
4298442999
}
4298543000
ht = Z_ARRVAL_P(container);
4298643001
ZEND_HASH_INDEX_FIND(ht, offset, value, fetch_dim_r_index_undef);

0 commit comments

Comments
 (0)