Skip to content

Commit f203edd

Browse files
committed
Fix leak of call->extra_named_params on internal __call
Fixes GH-12835 Closes GH-12836
1 parent 2303e76 commit f203edd

File tree

7 files changed

+83
-1
lines changed

7 files changed

+83
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ PHP NEWS
1010
. Fixed bug GH-12758 / GH-12768 (Invalid opline in OOM handlers within
1111
ZEND_FUNC_GET_ARGS and ZEND_BIND_STATIC). (Florian Engelhardt)
1212
. Fix various missing NULL checks. (nielsdos, dstogov)
13+
. Fixed bug GH-12835 (Leak of call->extra_named_params on internal __call).
14+
(ilutov)
1315

1416
- Date:
1517
. Fixed improbably integer overflow while parsing really large (or small)

Zend/zend_vm_def.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8783,6 +8783,9 @@ ZEND_VM_HANDLER(158, ZEND_CALL_TRAMPOLINE, ANY, ANY, SPEC(OBSERVER))
87838783
EG(current_execute_data) = call->prev_execute_data;
87848784

87858785
zend_vm_stack_free_args(call);
8786+
if (UNEXPECTED(call_info & ZEND_CALL_HAS_EXTRA_NAMED_PARAMS)) {
8787+
zend_free_extra_named_params(call->extra_named_params);
8788+
}
87868789
if (ret == &retval) {
87878790
zval_ptr_dtor(ret);
87888791
}

Zend/zend_vm_execute.h

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

ext/zend_test/test.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ static zend_class_entry *zend_test_ns2_ns_foo_class;
6565
static zend_class_entry *zend_test_unit_enum;
6666
static zend_class_entry *zend_test_string_enum;
6767
static zend_class_entry *zend_test_int_enum;
68+
static zend_class_entry *zend_test_magic_call;
6869
static zend_object_handlers zend_test_class_handlers;
6970

7071
static ZEND_FUNCTION(zend_test_func)
@@ -802,6 +803,24 @@ static ZEND_METHOD(ZendTestForbidDynamicCall, callStatic)
802803
zend_forbid_dynamic_call();
803804
}
804805

806+
static ZEND_METHOD(_ZendTestMagicCall, __call)
807+
{
808+
zend_string *name;
809+
zval *arguments;
810+
811+
ZEND_PARSE_PARAMETERS_START(2, 2)
812+
Z_PARAM_STR(name)
813+
Z_PARAM_ARRAY(arguments)
814+
ZEND_PARSE_PARAMETERS_END();
815+
816+
zval name_zv;
817+
ZVAL_STR(&name_zv, name);
818+
819+
zend_string_addref(name);
820+
Z_TRY_ADDREF_P(arguments);
821+
RETURN_ARR(zend_new_pair(&name_zv, arguments));
822+
}
823+
805824
PHP_INI_BEGIN()
806825
STD_PHP_INI_BOOLEAN("zend_test.replace_zend_execute_ex", "0", PHP_INI_SYSTEM, OnUpdateBool, replace_zend_execute_ex, zend_zend_test_globals, zend_test_globals)
807826
STD_PHP_INI_BOOLEAN("zend_test.register_passes", "0", PHP_INI_SYSTEM, OnUpdateBool, register_passes, zend_zend_test_globals, zend_test_globals)
@@ -914,6 +933,8 @@ PHP_MINIT_FUNCTION(zend_test)
914933
zend_test_string_enum = register_class_ZendTestStringEnum();
915934
zend_test_int_enum = register_class_ZendTestIntEnum();
916935

936+
zend_test_magic_call = register_class__ZendTestMagicCall();
937+
917938
zend_register_functions(NULL, ext_function_legacy, NULL, EG(current_module)->type);
918939

919940
// Loading via dl() not supported with the observer API

ext/zend_test/test.stub.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public function returnsThrowable(): Throwable {}
4747
static public function variadicTest(string|Iterator ...$elements) : static {}
4848
}
4949

50+
class _ZendTestMagicCall
51+
{
52+
public function __call(string $name, array $args): mixed {}
53+
}
54+
5055
class _ZendTestChildClass extends _ZendTestClass
5156
{
5257
public function returnsThrowable(): Exception {}

ext/zend_test/test_arginfo.h

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
GH-12835: call->extra_named_params leaks on internal __call
3+
--EXTENSIONS--
4+
zend_test
5+
--FILE--
6+
<?php
7+
$obj = new _ZendTestMagicCall;
8+
var_dump($obj->test('a', 'b', c: 'c'));
9+
?>
10+
--EXPECT--
11+
array(2) {
12+
[0]=>
13+
string(4) "test"
14+
[1]=>
15+
array(3) {
16+
[0]=>
17+
string(1) "a"
18+
[1]=>
19+
string(1) "b"
20+
["c"]=>
21+
string(1) "c"
22+
}
23+
}

0 commit comments

Comments
 (0)