Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Zend/tests/partial_application/compile_errors_007.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
--TEST--
PFA compile errors: positional after a named placeholder frees pending named positions
--DESCRIPTION--
A named placeholder allocates the named-positions table; a following
positional placeholder is a compile error. The table must not leak on
that bailout. The leak is only visible under valgrind/ASAN; this test
exercises the path so CI catches a regression.
--FILE--
<?php
function foo($a, $b) {}
$p = foo(b: ?, ?);
?>
--EXPECTF--
Fatal error: Cannot use positional argument after named argument in %s on line %d
12 changes: 12 additions & 0 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -3775,6 +3775,14 @@ static uint32_t zend_get_arg_num(const zend_function *fn, const zend_string *arg
return (uint32_t) -1;
}

static zend_always_inline void zend_free_pending_named_positions(zval *named_positions)
{
if (named_positions != NULL && !Z_ISUNDEF_P(named_positions)) {
zend_array_destroy(Z_ARRVAL_P(named_positions));
ZVAL_UNDEF(named_positions);
}
}

static uint32_t zend_compile_args_ex(
zend_ast *ast, const zend_function *fbc,
bool *may_have_extra_named_args,
Expand Down Expand Up @@ -3806,6 +3814,7 @@ static uint32_t zend_compile_args_ex(

if (arg->kind == ZEND_AST_UNPACK) {
if (uses_named_args) {
zend_free_pending_named_positions(named_positions);
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use argument unpacking after named arguments");
}
Expand Down Expand Up @@ -3857,6 +3866,7 @@ static uint32_t zend_compile_args_ex(
}

if (uses_variadic_placeholder) {
zend_free_pending_named_positions(named_positions);
zend_error_noreturn(E_COMPILE_ERROR,
"Variadic placeholder must be last");
}
Expand All @@ -3870,12 +3880,14 @@ static uint32_t zend_compile_args_ex(
&& arg->attr == ZEND_PLACEHOLDER_VARIADIC;

if (uses_named_args && !is_variadic_placeholder) {
zend_free_pending_named_positions(named_positions);
zend_error_noreturn(E_COMPILE_ERROR,
"Cannot use positional argument after named argument");
}

if (uses_variadic_placeholder) {
if (is_variadic_placeholder) {
zend_free_pending_named_positions(named_positions);
zend_error_noreturn(E_COMPILE_ERROR,
"Variadic placeholder may only appear once");
} else {
Expand Down
Loading