Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
4 changes: 4 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ PHP NEWS
. Fixed bug GH-16009 (Segmentation fault with frameless functions and
undefined CVs). (nielsdos)

- Reflection:
. Fixed bug GH-16122 (The return value of ReflectionFunction::getNamespaceName()
and ReflectionFunction::inNamespace() for closures is incorrect). (timwolla)

- SAPI:
. Fixed bug GHSA-9pqp-7h25-4f32 (Erroneous parsing of multipart form data).
(CVE-2024-8925) (Arnaud)
Expand Down
12 changes: 11 additions & 1 deletion Zend/tests/closure_067.phpt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
--TEST--
ReflectionFunction::getShortName() returns the full name for closures defined in namespaces.
ReflectionFunction::get{Short,Namespace}Name() and inNamespace() return the correct data for closures defined in namespaces.
--FILE--
<?php
namespace Foo;
Expand All @@ -14,7 +14,17 @@ class Bar {

$c = (new Bar())->baz();
$r = new \ReflectionFunction($c);
// Closures are not inside of a namespace, thus the short name is the full name.
var_dump($r->getShortName());
// The namespace is empty.
var_dump($r->getNamespaceName());
// The function is not inside of a namespace.
var_dump($r->inNamespace());
// And the namespace name + the short name together must be the full name.
var_dump($r->getNamespaceName() . ($r->inNamespace() ? '\\' : '') . $r->getShortName() === $r->getName());
?>
--EXPECT--
string(26) "{closure:Foo\Bar::baz():6}"
string(0) ""
bool(false)
bool(true)
16 changes: 15 additions & 1 deletion Zend/tests/closure_068.phpt
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
--TEST--
ReflectionFunction::getShortName() returns the short name for first class callables defined in namespaces.
ReflectionFunction::get{Short,Namespace}Name() and inNamespace() return the correct data for first class callables defined in namespaces.
--FILE--
<?php
namespace Foo;

function foo() {
}
$r = new \ReflectionFunction(foo(...));
$r2 = new \ReflectionFunction('Foo\\foo');
var_dump($r->getShortName());
var_dump($r->getNamespaceName());
var_dump($r->inNamespace());
var_dump($r->getNamespaceName() . ($r->inNamespace() ? '\\' : '') . $r->getShortName() === $r->getName());

var_dump($r->getShortName() === $r2->getShortName());
var_dump($r->getNamespaceName() === $r2->getNamespaceName());
var_dump($r->inNamespace() === $r2->inNamespace());
?>
--EXPECT--
string(3) "foo"
string(3) "Foo"
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
21 changes: 14 additions & 7 deletions ext/reflection/php_reflection.c
Original file line number Diff line number Diff line change
Expand Up @@ -3584,9 +3584,13 @@ ZEND_METHOD(ReflectionFunctionAbstract, inNamespace)

GET_REFLECTION_OBJECT_PTR(fptr);

zend_string *name = fptr->common.function_name;
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
RETURN_BOOL(backslash);
if ((fptr->common.fn_flags & (ZEND_ACC_CLOSURE | ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) {
zend_string *name = fptr->common.function_name;
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
RETURN_BOOL(backslash);
}

RETURN_FALSE;
}
/* }}} */

Expand All @@ -3602,11 +3606,14 @@ ZEND_METHOD(ReflectionFunctionAbstract, getNamespaceName)

GET_REFLECTION_OBJECT_PTR(fptr);

zend_string *name = fptr->common.function_name;
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
if (backslash) {
RETURN_STRINGL(ZSTR_VAL(name), backslash - ZSTR_VAL(name));
if ((fptr->common.fn_flags & (ZEND_ACC_CLOSURE | ZEND_ACC_FAKE_CLOSURE)) != ZEND_ACC_CLOSURE) {
zend_string *name = fptr->common.function_name;
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
if (backslash) {
RETURN_STRINGL(ZSTR_VAL(name), backslash - ZSTR_VAL(name));
}
}

RETURN_EMPTY_STRING();
}
/* }}} */
Expand Down