[php-src] Issue #22681: Reflection*::__toString() truncates on null bytes

[email protected] (DanielEScherzer) Fri, 10 Jul 2026 19:31:16 +0000
Newsgroups php.bugs
Message-ID <[email protected]>
Issue: https://github.com/php/php-src/issues/22681
Author: DanielEScherzer

After #22658 I figured I would check some other things, the following all truncate on null bytes in user-controlled values

<details>

<summary>ReflectionClass::__toString() from doc comment</summary>

```php
<?php

eval(<<<END
/** F\0oo */
class Demo {}
END
);

$r = new ReflectionClass('Demo');
echo $r;
var_dump( $r->getDocComment() );
```

</details><details>

<summary>ReflectionConstant::__toString() from constant name</summary>

```php
<?php

define("F\0oo", true);

$r = new ReflectionConstant("F\0oo");
echo $r;
var_dump( $r->getName() );
```

</details><details>

<summary>ReflectionClassConstant::__toString() from doc comment</summary>

```php
<?php

eval(<<<END
class Demo {
    /** F\0oo */
    public const DEMO = true;
}
END
);

$r = new ReflectionClassConstant('Demo', 'DEMO');
echo $r;
var_dump( $r->getDocComment() );
```

</details><details>

<summary>ReflectionEnum::__toString() with enum case documentation</summary>

```php
<?php

eval(<<<END
enum Demo {
    /** F\0oo */
    case DEMO;
}
END
);

$r = new ReflectionEnum('Demo');
echo $r;
var_dump( new ReflectionEnumUnitCase('Demo', 'DEMO')->getDocComment() );
```

</details><details>

<summary>ReflectionEnum::__toString() with backed enum value</summary>

```php
<?php

eval(<<<END
enum Demo: string {
    case DEMO = "F\0oo";
}
END
);

$r = new ReflectionEnum('Demo');
echo $r;
var_dump( new ReflectionEnumBackedCase('Demo', 'DEMO')->getBackingValue() );
```

</details><details>

<summary>ReflectionProperty::__toString() with doc comment</summary>

```php
<?php

eval(<<<END
class Demo {
    /** F\0oo */
    public \$prop;
}
END
);

$r = new ReflectionProperty('Demo', 'prop');
echo $r;
var_dump( $r->getDocComment() );
```

</details><details>

<summary>ReflectionProperty::__toString() with dynamic property name</summary>

```php
<?php

$obj = (object)["F\0oo" => true];
$r = new ReflectionProperty($obj, "F\0oo");
echo $r;
var_dump( $r->getDocComment() );
```

</details><details>

<summary>ReflectionExtension::__toString() with INI option value (also there is a weird `}` without a `{`, that should probably be fixed on master)</summary>

```php
<?php

ini_set('arg_separator.output', "f\0oo");
$r = new ReflectionExtension('core');
$str = (string)$r;
$index = strpos($str, 'Entry [ arg_separator.output');
$str = substr($str, $index);
$index = strpos($str, 'Entry', 1);
$str = substr($str, 0, $index);
echo $str . "\n";
var_dump( $r->getINIEntries()['arg_separator.output'] );
```

</details><details>

<summary>ReflectionFunctionAbstract::__toString() with doc comment</summary>

```php
<?php

eval(<<<END
/** F\0oo */
function demo() {}

class Demo {
    /** F\0oo */
    public function demo() {}
}
END
);

$r = new ReflectionFunction('demo');
echo $r;
var_dump( $r->getDocComment() );

$r = new ReflectionMethod(Demo::class, 'demo');
echo $r;
var_dump( $r->getDocComment() );
```

</details>