mirror of
https://github.com/php/php-src.git
synced 2026-03-24 00:02:20 +01:00
Fix FETCH_OBJ_UNSET IS_UNDEF result
UNSET_OBJ et al. do not expect to find IS_UNDEF results for IS_INDIRECT vars. To solve this, return IS_NULL from FETCH_OBJ_UNSET when properties are uninitialized. Do the same for FETCH_STATIC_PROP_IS, as we're otherwise copying IS_UNDEF into the VAR result, which is not a valid value for VAR. Fixes OSS-Fuzz #429429090 Closes GH-19160
This commit is contained in:
2
NEWS
2
NEWS
@@ -8,6 +8,8 @@ PHP NEWS
|
|||||||
. It is now possible to use reference assign on WeakMap without the key
|
. It is now possible to use reference assign on WeakMap without the key
|
||||||
needing to be present beforehand. (ndossche)
|
needing to be present beforehand. (ndossche)
|
||||||
. Added `clamp()`. (kylekatarnls, thinkverse)
|
. Added `clamp()`. (kylekatarnls, thinkverse)
|
||||||
|
. Fix OSS-Fuzz #429429090 (Failed assertion on unset() with uninitialized
|
||||||
|
container). (ilutov)
|
||||||
|
|
||||||
- Date:
|
- Date:
|
||||||
. Update timelib to 2022.16. (Derick)
|
. Update timelib to 2022.16. (Derick)
|
||||||
|
|||||||
@@ -3840,7 +3840,7 @@ static zend_always_inline zend_result _zend_update_type_info(
|
|||||||
tmp &= ~MAY_BE_RC1;
|
tmp &= ~MAY_BE_RC1;
|
||||||
}
|
}
|
||||||
if (opline->opcode == ZEND_FETCH_STATIC_PROP_IS) {
|
if (opline->opcode == ZEND_FETCH_STATIC_PROP_IS) {
|
||||||
tmp |= MAY_BE_UNDEF;
|
tmp |= MAY_BE_NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
|
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);
|
||||||
|
|||||||
20
Zend/tests/oss_fuzz_429429090.phpt
Normal file
20
Zend/tests/oss_fuzz_429429090.phpt
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
--TEST--
|
||||||
|
OSS-Fuzz #429429090: FETCH_OBJ_UNSET IS_UNDEF result
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class C {
|
||||||
|
public D $x;
|
||||||
|
static D $y;
|
||||||
|
}
|
||||||
|
|
||||||
|
$c = new C();
|
||||||
|
isset($c->x[0]->prop);
|
||||||
|
unset($c->x[0]->prop);
|
||||||
|
isset(C::$y[0]->prop);
|
||||||
|
unset(C::$y[0]->prop);
|
||||||
|
|
||||||
|
?>
|
||||||
|
===DONE===
|
||||||
|
--EXPECT--
|
||||||
|
===DONE===
|
||||||
@@ -3626,6 +3626,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
|
|||||||
} else if (UNEXPECTED(Z_ISERROR_P(ptr))) {
|
} else if (UNEXPECTED(Z_ISERROR_P(ptr))) {
|
||||||
ZVAL_ERROR(result);
|
ZVAL_ERROR(result);
|
||||||
goto end;
|
goto end;
|
||||||
|
} else if (type == BP_VAR_UNSET && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
|
||||||
|
ZVAL_NULL(result);
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
ZVAL_INDIRECT(result, ptr);
|
ZVAL_INDIRECT(result, ptr);
|
||||||
@@ -3777,6 +3780,11 @@ static zend_never_inline zval* zend_fetch_static_property_address_ex(zend_proper
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (UNEXPECTED(Z_TYPE_P(result) == IS_UNDEF)
|
||||||
|
&& (fetch_type == BP_VAR_IS || fetch_type == BP_VAR_UNSET)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
*prop_info = property_info;
|
*prop_info = property_info;
|
||||||
|
|
||||||
if (EXPECTED(op1_type == IS_CONST)
|
if (EXPECTED(op1_type == IS_CONST)
|
||||||
|
|||||||
@@ -1866,7 +1866,7 @@ ZEND_VM_INLINE_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
|
|||||||
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
||||||
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
||||||
if (UNEXPECTED(!prop)) {
|
if (UNEXPECTED(!prop)) {
|
||||||
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
|
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
|
||||||
prop = &EG(uninitialized_zval);
|
prop = &EG(uninitialized_zval);
|
||||||
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
||||||
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
||||||
|
|||||||
4
Zend/zend_vm_execute.h
generated
4
Zend/zend_vm_execute.h
generated
@@ -895,7 +895,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_
|
|||||||
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
||||||
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
||||||
if (UNEXPECTED(!prop)) {
|
if (UNEXPECTED(!prop)) {
|
||||||
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
|
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
|
||||||
prop = &EG(uninitialized_zval);
|
prop = &EG(uninitialized_zval);
|
||||||
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
||||||
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
||||||
@@ -112163,7 +112163,7 @@ static zend_always_inline ZEND_OPCODE_HANDLER_RET zend_fetch_static_prop_helper_
|
|||||||
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
|
||||||
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
|
||||||
if (UNEXPECTED(!prop)) {
|
if (UNEXPECTED(!prop)) {
|
||||||
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
|
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
|
||||||
prop = &EG(uninitialized_zval);
|
prop = &EG(uninitialized_zval);
|
||||||
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
|
||||||
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)
|
||||||
|
|||||||
Reference in New Issue
Block a user