Skip to content

Commit 36cf319

Browse files
committed
Added support for passing new class as parameter defaults.
Added exception handling for passing `default` to required parameters. Fixed default_value leak in ZEND_FETCH_DEFAULT_ARG handler.
1 parent 4ddca1d commit 36cf319

7 files changed

+89
-1
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Tests passing default to a required parameter of an internal class
3+
--FILE--
4+
<?php
5+
6+
DateTime::createFromInterface(default);
7+
?>
8+
--EXPECTF--
9+
Fatal error: Uncaught ValueError: Cannot pass default to required parameter 1 of DateTime::createFromInterface() in %s:%d
10+
Stack trace:%a
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
--TEST--
2+
Tests passing default to a required parameter of an internal function
3+
--FILE--
4+
<?php
5+
6+
json_encode(default);
7+
?>
8+
--EXPECTF--
9+
Fatal error: Uncaught ValueError: Cannot pass default to required parameter 1 of json_encode() in %s:%d
10+
Stack trace:%a

Zend/tests/default_expression/internal function.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Tests passing default to an internal function parameter
33
--FILE--
44
<?php
55

6-
json_encode([], depth: $D = default);
6+
json_encode([], 0, $D = default);
77
var_dump($D);
88
?>
99
--EXPECT--
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Tests passing default as a named argument
3+
--FILE--
4+
<?php
5+
6+
json_encode([], depth: $D = default);
7+
var_dump($D);
8+
9+
function F($V = 'Alfa', $V2 = 1) {
10+
var_dump($V2);
11+
}
12+
F(V2: default + 1);
13+
?>
14+
--EXPECT--
15+
int(512)
16+
int(2)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
--TEST--
2+
Test passing default to a parameter with a new class as the default
3+
--FILE--
4+
<?php
5+
6+
function F($V = new stdClass) {}
7+
F($D = default);
8+
var_dump($D);
9+
?>
10+
--EXPECT--
11+
object(stdClass)#1 (0) {
12+
}

Zend/zend_vm_def.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9821,10 +9821,29 @@ ZEND_VM_HANDLER(210, ZEND_FETCH_DEFAULT_ARG, UNUSED|NUM, UNUSED)
98219821
pr.arg_info = &called_func->common.arg_info[pr.offset];
98229822
pr.fptr = called_func;
98239823

9824+
if (pr.required) {
9825+
zend_value_error("Cannot pass default to required parameter %u of %s%s%s()",
9826+
opline->op1.num,
9827+
called_func->common.scope ? ZSTR_VAL(called_func->common.scope->name) : "",
9828+
called_func->common.scope ? "::" : "",
9829+
ZSTR_VAL(called_func->common.function_name)
9830+
);
9831+
HANDLE_EXCEPTION();
9832+
}
9833+
98249834
zval default_value;
98259835
get_parameter_default(&default_value, &pr);
98269836

9837+
// Evaluate AST value, e.g. new class.
9838+
if (Z_TYPE(default_value) == IS_CONSTANT_AST) {
9839+
if (UNEXPECTED(zval_update_constant_ex(&default_value, called_func->common.scope) != SUCCESS)) {
9840+
HANDLE_EXCEPTION();
9841+
}
9842+
}
9843+
98279844
ZVAL_COPY(EX_VAR(opline->result.var), &default_value);
9845+
zval_ptr_dtor(&default_value);
9846+
98289847
ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
98299848
}
98309849

Zend/zend_vm_execute.h

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

0 commit comments

Comments
 (0)