Repository navigation
Reflection exception messages truncate on null bytes #22905
Copy link
Copy link
Closed
Labels
Description
After #22681 I looked into exception messages:
Reflection*::getAttributes() with ReflectionAttribute::IS_INSTANCEOF
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->getAttributes("foo\0bar", ReflectionAttribute::IS_INSTANCEOF);ReflectionFunction::__construct()
<?php
new ReflectionFunction("foo\0bar");ReflectionParameter::__construct() with string function
<?php
new ReflectionParameter("foo\0bar", 0);ReflectionParameter::__construct() with array with class name
<?php
new ReflectionParameter(["foo\0bar", ""], 0);ReflectionParameter::__construct() with array with method name
<?php
class Demo {}
new ReflectionParameter([Demo::class, "foo\0bar"], 0);ReflectionMethod::__construct() with class name
<?php
new ReflectionMethod("foo\0bar", "");ReflectionMethod::__construct() with method name
<?php
class Demo {}
new ReflectionMethod(Demo::class, "foo\0bar");the above should also apply to ReflectionMethod::createFromMethodName() - they share the same lookup code
ReflectionClassConstant::__construct() with class name
<?php
new ReflectionClassConstant("foo\0bar", "");ReflectionClassConstant::__construct() with constant name
<?php
class Demo {}
new ReflectionClassConstant(Demo::class, "foo\0bar");ReflectionClass::__construct()
<?php
new ReflectionClass("foo\0bar");ReflectionClass::getStaticPropertyValue()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->getStaticPropertyValue("foo\0bar");ReflectionClass::setStaticPropertyValue()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->setStaticPropertyValue("foo\0bar", 123);ReflectionClass::getMethod()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->getMethod("foo\0bar");ReflectionClass::getProperty()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->getProperty("foo\0bar");ReflectionClass::getProperty() (fully qualified)
<?php
class Base {}
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->getProperty("Base::foo\0bar");ReflectionClass::isSubclassOf()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->isSubclassOf("foo\0bar");ReflectionClass::implementsInterface()
<?php
class Demo {}
$r = new ReflectionClass(Demo::class);
$r->implementsInterface("foo\0bar");ReflectionProperty::__construct() with class name
<?php
new ReflectionProperty("foo\0bar", "");ReflectionProperty::__construct() with property name
<?php
class Demo {}
new ReflectionProperty(Demo::class, "foo\0bar");ReflectionProperty::skipLazyInitialization() with property name
<?php
$o = (object)["foo\0bar" => "baz"];
$r = new ReflectionProperty($o, "foo\0bar");
$r->skipLazyInitialization($o);also affects anything else using reflection_property_check_lazy_compatible()
ReflectionEnum::getCase() with missing case
<?php
enum Demo {}
$r = new ReflectionEnum(Demo::class);
$r->getCase("foo\0bar");ReflectionConstant::__construct()
<?php
new ReflectionConstant("foo\0bar");Reactions are currently unavailable
Activity
DanielEScherzer commentedon Jul 28, 2026
@Girgias on #22685 on the initial version you wrote
with regards to stuff like
unfortunately, there doesn't seem to be an easy way to do something similar for exception message printing, and there isn't an _unchecked variant of
zend_throw_exception_ex()or similar. Would you be okay with me using%Shere in the exception messages (for 8.4+) and then adding an _unchecked variant of the throwing for master?Girgias commentedon Jul 28, 2026
Yeah, I guess for a bugfix that's fine.
DanielEScherzer commentedon Jul 29, 2026
Turns out even using
%Sdoesn't work without some extra fixesbecause
zend_throw_errorforwards tozend_throw_exceptionwhich will just usestrlenzend_throw_exception_exalso forwards tozend_throw_exception(fixed in 8.5 by you in Minor refactorings to zend_exceptions() #16684)DanielEScherzer commentedon Aug 3, 2026
Also
ReflectionZendExtension::__construct():and
ReflectionExtension::__construct():phpGH-22905: avoid truncation on null bytes in reflection exceptions
Merge branch 'PHP-8.5'
Merge branch 'PHP-8.4' into PHP-8.5