diff --git a/NEWS b/NEWS index ab0e1f210dd2e..292ab3b4d166a 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,7 @@ PHP NEWS - Core: . Fixed oss-fuzz #60011 (Mis-compilation of by-reference nullsafe operator). (ilutov) + . Fixed use-of-uninitialized-value with ??= on assert. (ilutov) - Date: . Fixed bug GH-11368 (Date modify returns invalid datetime). (Derick) diff --git a/Zend/tests/gh11580.phpt b/Zend/tests/gh11580.phpt new file mode 100644 index 0000000000000..194c8b5a1aa0e --- /dev/null +++ b/Zend/tests/gh11580.phpt @@ -0,0 +1,13 @@ +--TEST-- +GH-11580: assert() with ??= operator can lead to use-of-uninitialized-value +--INI-- +zend.assertions=0 +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: Undefined constant "y" in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 59e4d369595ae..d470385cc98e0 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -4083,6 +4083,10 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string zend_op *opline; uint32_t check_op_number = get_next_op_number(); + /* Assert expression may not be memoized and reused as it may not actually be evaluated. */ + int orig_memoize_mode = CG(memoize_mode); + CG(memoize_mode) = ZEND_MEMOIZE_NONE; + zend_emit_op(NULL, ZEND_ASSERT_CHECK, NULL, NULL); if (fbc && fbc_is_finalized(fbc)) { @@ -4116,6 +4120,8 @@ static void zend_compile_assert(znode *result, zend_ast_list *args, zend_string opline = &CG(active_op_array)->opcodes[check_op_number]; opline->op2.opline_num = get_next_op_number(); SET_NODE(opline->result, result); + + CG(memoize_mode) = orig_memoize_mode; } else { if (!fbc) { zend_string_release_ex(name, 0);