Merge branch 'PHP-8.3' into PHP-8.4

* PHP-8.3:
  Fix circumvented type check with return by ref + finally
This commit is contained in:
Ilija Tovilo 2025-08-01 00:36:28 +02:00
commit b3f4863373
No known key found for this signature in database
GPG key ID: 115CEA7A713E12E9
3 changed files with 38 additions and 0 deletions

2
NEWS
View file

@ -22,6 +22,8 @@ PHP NEWS
. Fixed bug GH-19326 (Calling Generator::throw() on a running generator with
a non-Generator delegate crashes). (Arnaud)
. Fixed bug GH-19280 (Stale array iterator position on rehashing). (ilutov)
. Fixed bug GH-18736 (Circumvented type check with return by ref + finally).
(ilutov)
- FTP:
. Fix theoretical issues with hrtime() not being available. (nielsdos)

24
Zend/tests/gh18736.phpt Normal file
View file

@ -0,0 +1,24 @@
--TEST--
GH-18736: Circumvented type check with return by ref + finally
--FILE--
<?php
function &test(): int {
$x = 0;
try {
return $x;
} finally {
$x = 'test';
}
}
try {
$x = &test();
var_dump($x);
} catch (Error $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
test(): Return value must be of type int, string returned

View file

@ -5725,8 +5725,20 @@ static void zend_compile_return(zend_ast *ast) /* {{{ */
expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0);
}
uint32_t opnum_before_finally = get_next_op_number();
zend_handle_loops_and_finally((expr_node.op_type & (IS_TMP_VAR | IS_VAR)) ? &expr_node : NULL);
/* Content of reference might have changed in finally, repeat type check. */
if (by_ref
/* Check if any opcodes were emitted since the last return type check. */
&& opnum_before_finally != get_next_op_number()
&& !is_generator
&& (CG(active_op_array)->fn_flags & ZEND_ACC_HAS_RETURN_TYPE)) {
zend_emit_return_type_check(
expr_ast ? &expr_node : NULL, CG(active_op_array)->arg_info - 1, 0);
}
opline = zend_emit_op(NULL, by_ref ? ZEND_RETURN_BY_REF : ZEND_RETURN,
&expr_node, NULL);