Skip to content

Commit 8b4ef3a

Browse files
committed
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 phpGH-19160
1 parent eca7494 commit 8b4ef3a

File tree

6 files changed

+34
-4
lines changed

6 files changed

+34
-4
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ PHP NEWS
88
. It is now possible to use reference assign on WeakMap without the key
99
needing to be present beforehand. (ndossche)
1010
. Added `clamp()`. (kylekatarnls, thinkverse)
11+
. Fix OSS-Fuzz #429429090 (Failed assertion on unset() with uninitialized
12+
container). (ilutov)
1113

1214
- Date:
1315
. Update timelib to 2022.16. (Derick)

Zend/Optimizer/zend_inference.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3840,7 +3840,7 @@ static zend_always_inline zend_result _zend_update_type_info(
38403840
tmp &= ~MAY_BE_RC1;
38413841
}
38423842
if (opline->opcode == ZEND_FETCH_STATIC_PROP_IS) {
3843-
tmp |= MAY_BE_UNDEF;
3843+
tmp |= MAY_BE_NULL;
38443844
}
38453845
}
38463846
UPDATE_SSA_TYPE(tmp, ssa_op->result_def);

Zend/tests/oss_fuzz_429429090.phpt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
OSS-Fuzz #429429090: FETCH_OBJ_UNSET IS_UNDEF result
3+
--FILE--
4+
<?php
5+
6+
class C {
7+
public D $x;
8+
static D $y;
9+
}
10+
11+
$c = new C();
12+
isset($c->x[0]->prop);
13+
unset($c->x[0]->prop);
14+
isset(C::$y[0]->prop);
15+
unset(C::$y[0]->prop);
16+
17+
?>
18+
===DONE===
19+
--EXPECT--
20+
===DONE===

Zend/zend_execute.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3626,6 +3626,9 @@ static zend_always_inline void zend_fetch_property_address(zval *result, zval *c
36263626
} else if (UNEXPECTED(Z_ISERROR_P(ptr))) {
36273627
ZVAL_ERROR(result);
36283628
goto end;
3629+
} else if (type == BP_VAR_UNSET && UNEXPECTED(Z_TYPE_P(ptr) == IS_UNDEF)) {
3630+
ZVAL_NULL(result);
3631+
goto end;
36293632
}
36303633

36313634
ZVAL_INDIRECT(result, ptr);
@@ -3777,6 +3780,11 @@ static zend_never_inline zval* zend_fetch_static_property_address_ex(zend_proper
37773780
return NULL;
37783781
}
37793782

3783+
if (UNEXPECTED(Z_TYPE_P(result) == IS_UNDEF)
3784+
&& (fetch_type == BP_VAR_IS || fetch_type == BP_VAR_UNSET)) {
3785+
return NULL;
3786+
}
3787+
37803788
*prop_info = property_info;
37813789

37823790
if (EXPECTED(op1_type == IS_CONST)

Zend/zend_vm_def.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1866,7 +1866,7 @@ ZEND_VM_INLINE_HELPER(zend_fetch_static_prop_helper, ANY, ANY, int type)
18661866
&prop_info, opline->extended_value & ~ZEND_FETCH_OBJ_FLAGS, type,
18671867
type == BP_VAR_W ? opline->extended_value : 0 OPLINE_CC EXECUTE_DATA_CC);
18681868
if (UNEXPECTED(!prop)) {
1869-
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS));
1869+
ZEND_ASSERT(EG(exception) || (type == BP_VAR_IS) || (type == BP_VAR_UNSET));
18701870
prop = &EG(uninitialized_zval);
18711871
} else if (UNEXPECTED(prop_info->flags & ZEND_ACC_PPP_SET_MASK)
18721872
&& (type == BP_VAR_W || type == BP_VAR_RW || type == BP_VAR_UNSET)

Zend/zend_vm_execute.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)