Commit fc30d3138ac for php.net

commit fc30d3138acfdb3268bcf9f86c56978304ddf398
Merge: 4fa10e25136 fd7e1e21613
Author: Daniel Scherzer <daniel.e.scherzer@gmail.com>
Date:   Mon Jul 13 14:24:08 2026 -0700

    Merge branch 'PHP-8.5'

    * PHP-8.5:
      NEWS
      GH-22681: avoid truncation on null bytes in `Reflection*::__toString()`
      Add regression tests for `Reflection*::__toString()` with null bytes

diff --cc NEWS
index 702d9d04fe3,93a4cf331b6..6f2e69aa829
--- a/NEWS
+++ b/NEWS
@@@ -91,8 -82,16 +91,10 @@@ PH
      always fail during phpdbg's signal-safe interruption path. (jorgsowa)

  - Reflection:
 -  . Fixed bug GH-22324 (Ignore leading namespace separator in
 -    ReflectionParameter::__construct()). (jorgsowa)
 -  . Fixed bug GH-22441 (ReflectionClass::hasProperty() and getProperty() ignore
 -    dynamic properties shadowing a private parent property). (iliaal)
 -  . Fixed bug GH-22658 (ReflectionConstant::__toString() with a string value
 -    with null bytes truncates output). (DanielEScherzer)
    . Fixed bug GH-22683 (Reflection(Class)Constant::__toString() should not warn
      on NAN conversions). (Khaled Alam)
+   . Fixed bug GH-22681 (Reflection*::__toString() truncates on null bytes).
+     (DanielEScherzer)

  - Session:
    . Fixed bug GH-21314 (Different session garbage collector behavior between
diff --cc ext/reflection/php_reflection.c
index 13df0b2bbb4,a3e996b654c..ef620369bb4
--- a/ext/reflection/php_reflection.c
+++ b/ext/reflection/php_reflection.c
@@@ -294,9 -302,9 +294,9 @@@ static zend_object *reflection_objects_
  }
  /* }}} */

- static void _const_string(smart_str *str, const char *name, zval *value, const char *indent);
+ static void _const_string(smart_str *str, const zend_string *name, zval *value, const char *indent);
 -static void _function_string(smart_str *str, zend_function *fptr, zend_class_entry *scope, const char* indent);
 -static void _property_string(smart_str *str, zend_property_info *prop, const zend_string *prop_name, const char* indent);
 +static void _function_string(smart_str *str, const zend_function *fptr, const zend_class_entry *scope, const char* indent);
- static void _property_string(smart_str *str, const zend_property_info *prop, const char *prop_name, const char* indent);
++static void _property_string(smart_str *str, const zend_property_info *prop, const zend_string *prop_name, const char* indent);
  static void _class_const_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char* indent);
  static void _enum_case_string(smart_str *str, const zend_string *name, zend_class_constant *c, const char* indent);
  static void _class_string(smart_str *str, zend_class_entry *ce, zval *obj, const char *indent);
@@@ -869,12 -888,16 +872,16 @@@ static void _function_string(smart_str
  	 * swallowed, leading to an unaligned comment.
  	 */
  	if (fptr->type == ZEND_USER_FUNCTION && fptr->op_array.doc_comment) {
- 		smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->op_array.doc_comment));
+ 		smart_str_appends(str, indent);
+ 		smart_str_append(str, fptr->op_array.doc_comment);
+ 		smart_str_appendc(str, '\n');
  	} else if (fptr->type == ZEND_INTERNAL_FUNCTION && fptr->internal_function.doc_comment) {
- 		smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(fptr->internal_function.doc_comment));
+ 		smart_str_appends(str, indent);
+ 		smart_str_append(str, fptr->internal_function.doc_comment);
+ 		smart_str_appendc(str, '\n');
  	}

 -	smart_str_appendl(str, indent, strlen(indent));
 +	smart_str_appends(str, indent);
  	smart_str_appends(str, fptr->common.fn_flags & ZEND_ACC_CLOSURE ? "Closure [ " : (fptr->common.scope ? "Method [ " : "Function [ "));
  	smart_str_appends(str, (fptr->type == ZEND_USER_FUNCTION) ? "<user" : "<internal");
  	if (fptr->common.fn_flags & ZEND_ACC_DEPRECATED) {
@@@ -979,10 -1004,12 +986,12 @@@ static zval *property_get_default(cons
  }

  /* {{{ _property_string */
- static void _property_string(smart_str *str, const zend_property_info *prop, const char *prop_name, const char* indent)
 -static void _property_string(smart_str *str, zend_property_info *prop, const zend_string *prop_name, const char* indent)
++static void _property_string(smart_str *str, const zend_property_info *prop, const zend_string *prop_name, const char* indent)
  {
  	if (prop && prop->doc_comment) {
- 		smart_str_append_printf(str, "%s%s\n", indent, ZSTR_VAL(prop->doc_comment));
+ 		smart_str_appends(str, indent);
+ 		smart_str_append(str, prop->doc_comment);
+ 		smart_str_appendc(str, '\n');
  	}
  	smart_str_append_printf(str, "%sProperty [ ", indent);
  	if (!prop) {
@@@ -1032,13 -1061,17 +1043,17 @@@
  			smart_str_appendc(str, ' ');
  			zend_string_release(type_str);
  		}
+ 		smart_str_appendc(str, '$');
  		if (!prop_name) {
  			const char *class_name;
- 			zend_unmangle_property_name(prop->name, &class_name, &prop_name);
+ 			const char *prop_name_cstr;
+ 			zend_unmangle_property_name(prop->name, &class_name, &prop_name_cstr);
+ 			smart_str_appends(str, prop_name_cstr);
+ 		} else {
+ 			smart_str_append(str, prop_name);
  		}
- 		smart_str_append_printf(str, "$%s", prop_name);

 -		zval *default_value = property_get_default(prop);
 +		const zval *default_value = property_get_default(prop);
  		if (default_value && !Z_ISUNDEF_P(default_value)) {
  			smart_str_appends(str, " = ");
  			format_default_value(str, default_value);
@@@ -1092,11 -1125,23 +1107,23 @@@ static void _extension_ini_string(cons
  		}

  		smart_str_appends(str, "> ]\n");
- 		smart_str_append_printf(str, "      Current = '%s'\n", ini_entry->value ? ZSTR_VAL(ini_entry->value) : "");
+ 		if (ini_entry->value) {
 -			smart_str_append_printf(str, "    %s  Current = '", indent);
++			smart_str_appends(str, "      Current = '");
+ 			smart_str_append(str, ini_entry->value);
+ 			smart_str_appends(str, "'\n");
+ 		} else {
 -			smart_str_append_printf(str, "    %s  Current = ''\n", indent);
++			smart_str_appends(str, "      Current = ''\n");
+ 		}
  		if (ini_entry->modified) {
- 			smart_str_append_printf(str, "      Default = '%s'\n", ini_entry->orig_value ? ZSTR_VAL(ini_entry->orig_value) : "");
+ 			if (ini_entry->orig_value) {
 -				smart_str_append_printf(str, "    %s  Default = '", indent);
++				smart_str_appends(str, "      Default = '");
+ 				smart_str_append(str, ini_entry->orig_value);
+ 				smart_str_appends(str, "'\n");
+ 			} else {
 -				smart_str_append_printf(str, "    %s  Default = ''\n", indent);
++				smart_str_appends(str, "      Default = ''\n");
+ 			}
  		}
 -		smart_str_append_printf(str, "    %s}\n", indent);
 +		smart_str_appends(str, "    }\n");
  	}
  }
  /* }}} */