mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
reflection: Fix the return value of ReflectionFunction::{getNamespaceName,inNamespace}() for closures (#16129)
* reflection: Fix the return value of ReflectionFunction::{getNamespaceName,inNamespace}() for closures Fixes GH-16122 * reflection: Clean up implementation of `ReflectionFunctionAbstract::inNamespace()` * reflection: Clean up implementation of `ReflectionFunctionAbstract::getNamespaceName()`
This commit is contained in:
parent
ebee8df27e
commit
a1cc091808
4 changed files with 38 additions and 2 deletions
4
NEWS
4
NEWS
|
@ -37,6 +37,10 @@ PHP NEWS
|
||||||
. Fixed bug GH-16009 (Segmentation fault with frameless functions and
|
. Fixed bug GH-16009 (Segmentation fault with frameless functions and
|
||||||
undefined CVs). (nielsdos)
|
undefined CVs). (nielsdos)
|
||||||
|
|
||||||
|
- Reflection:
|
||||||
|
. Fixed bug GH-16122 (The return value of ReflectionFunction::getNamespaceName()
|
||||||
|
and ReflectionFunction::inNamespace() for closures is incorrect). (timwolla)
|
||||||
|
|
||||||
- SAPI:
|
- SAPI:
|
||||||
. Fixed bug GHSA-9pqp-7h25-4f32 (Erroneous parsing of multipart form data).
|
. Fixed bug GHSA-9pqp-7h25-4f32 (Erroneous parsing of multipart form data).
|
||||||
(CVE-2024-8925) (Arnaud)
|
(CVE-2024-8925) (Arnaud)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--TEST--
|
--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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
namespace Foo;
|
namespace Foo;
|
||||||
|
@ -14,7 +14,17 @@ class Bar {
|
||||||
|
|
||||||
$c = (new Bar())->baz();
|
$c = (new Bar())->baz();
|
||||||
$r = new \ReflectionFunction($c);
|
$r = new \ReflectionFunction($c);
|
||||||
|
// Closures are not inside of a namespace, thus the short name is the full name.
|
||||||
var_dump($r->getShortName());
|
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--
|
--EXPECT--
|
||||||
string(26) "{closure:Foo\Bar::baz():6}"
|
string(26) "{closure:Foo\Bar::baz():6}"
|
||||||
|
string(0) ""
|
||||||
|
bool(false)
|
||||||
|
bool(true)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
--TEST--
|
--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--
|
--FILE--
|
||||||
<?php
|
<?php
|
||||||
namespace Foo;
|
namespace Foo;
|
||||||
|
@ -7,7 +7,21 @@ namespace Foo;
|
||||||
function foo() {
|
function foo() {
|
||||||
}
|
}
|
||||||
$r = new \ReflectionFunction(foo(...));
|
$r = new \ReflectionFunction(foo(...));
|
||||||
|
$r2 = new \ReflectionFunction('Foo\\foo');
|
||||||
var_dump($r->getShortName());
|
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--
|
--EXPECT--
|
||||||
string(3) "foo"
|
string(3) "foo"
|
||||||
|
string(3) "Foo"
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
bool(true)
|
||||||
|
|
|
@ -3584,6 +3584,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, inNamespace)
|
||||||
|
|
||||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||||
|
|
||||||
|
if ((fptr->common.fn_flags & (ZEND_ACC_CLOSURE | ZEND_ACC_FAKE_CLOSURE)) == ZEND_ACC_CLOSURE) {
|
||||||
|
RETURN_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
zend_string *name = fptr->common.function_name;
|
zend_string *name = fptr->common.function_name;
|
||||||
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
|
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
|
||||||
RETURN_BOOL(backslash);
|
RETURN_BOOL(backslash);
|
||||||
|
@ -3602,6 +3606,10 @@ ZEND_METHOD(ReflectionFunctionAbstract, getNamespaceName)
|
||||||
|
|
||||||
GET_REFLECTION_OBJECT_PTR(fptr);
|
GET_REFLECTION_OBJECT_PTR(fptr);
|
||||||
|
|
||||||
|
if ((fptr->common.fn_flags & (ZEND_ACC_CLOSURE | ZEND_ACC_FAKE_CLOSURE)) == ZEND_ACC_CLOSURE) {
|
||||||
|
RETURN_EMPTY_STRING();
|
||||||
|
}
|
||||||
|
|
||||||
zend_string *name = fptr->common.function_name;
|
zend_string *name = fptr->common.function_name;
|
||||||
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
|
const char *backslash = zend_memrchr(ZSTR_VAL(name), '\\', ZSTR_LEN(name));
|
||||||
if (backslash) {
|
if (backslash) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue