diff --git a/Zend/zend.c b/Zend/zend.c index b4a084b1f95c..8fea4e57e5e6 100644 --- a/Zend/zend.c +++ b/Zend/zend.c @@ -1772,7 +1772,6 @@ ZEND_API void zend_free_recorded_errors(void) ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const char *format, ...) /* {{{ */ { va_list va; - char *message = NULL; if (!exception_ce) { exception_ce = zend_ce_error; @@ -1784,16 +1783,20 @@ ZEND_API ZEND_COLD void zend_throw_error(zend_class_entry *exception_ce, const c } va_start(va, format); - zend_vspprintf(&message, 0, format, va); + zend_string *message = zend_vstrpprintf(0, format, va); //TODO: we can't convert compile-time errors to exceptions yet??? if (EG(current_execute_data) && !CG(in_compilation)) { - zend_throw_exception(exception_ce, message, 0); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + // Use "%S" so that the message can contain null bytes. + const char *format = "%S"; + zend_throw_exception_ex(exception_ce, 0, format, message); } else { - zend_error_noreturn(E_ERROR, "%s", message); + zend_error_noreturn(E_ERROR, "%s", ZSTR_VAL(message)); } - efree(message); + zend_string_release(message); va_end(va); } /* }}} */ diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 446aba4ee4a2..2607cae594c5 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -888,14 +888,13 @@ ZEND_API ZEND_COLD zend_object *zend_throw_exception(zend_class_entry *exception ZEND_API ZEND_COLD zend_object *zend_throw_exception_ex(zend_class_entry *exception_ce, zend_long code, const char *format, ...) /* {{{ */ { va_list arg; - char *message; zend_object *obj; va_start(arg, format); - zend_vspprintf(&message, 0, format, arg); + zend_string *msg_str = zend_vstrpprintf(0, format, arg); va_end(arg); - obj = zend_throw_exception(exception_ce, message, code); - efree(message); + obj = zend_throw_exception_zstr(exception_ce, msg_str, code); + zend_string_release(msg_str); return obj; } /* }}} */ diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 0945c9574c62..90c8d9f0810b 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1298,7 +1298,10 @@ static void reflect_attributes(INTERNAL_FUNCTION_PARAMETERS, HashTable *attribut if (name && (flags & REFLECTION_ATTRIBUTE_IS_INSTANCEOF)) { if (NULL == (base = zend_lookup_class(name))) { if (!EG(exception)) { - zend_throw_error(NULL, "Class \"%s\" not found", ZSTR_VAL(name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" not found"; + zend_throw_error(NULL, format, name); } RETURN_THROWS(); @@ -1704,8 +1707,11 @@ ZEND_METHOD(ReflectionFunction, __construct) } if (fptr == NULL) { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Function %S() does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Function %s() does not exist", ZSTR_VAL(fname)); + format, fname); RETURN_THROWS(); } } @@ -2522,8 +2528,11 @@ ZEND_METHOD(ReflectionParameter, __construct) zend_string_release(lcname); } if (!fptr) { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Function %S() does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Function %s() does not exist", Z_STRVAL_P(reference)); + format, Z_STR_P(reference)); RETURN_THROWS(); } ce = fptr->common.scope; @@ -2550,8 +2559,11 @@ ZEND_METHOD(ReflectionParameter, __construct) return; } if ((ce = zend_lookup_class(name)) == NULL) { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Class \"%s\" does not exist", ZSTR_VAL(name)); + format, name); zend_string_release(name); RETURN_THROWS(); } @@ -2570,8 +2582,11 @@ ZEND_METHOD(ReflectionParameter, __construct) /* nothing to do. don't set is_closure since is the invoke handler, not the closure itself */ } else if ((fptr = zend_hash_find_ptr(&ce->function_table, lcname)) == NULL) { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Method %S::%S() does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + format, ce->name, name); zend_string_release(name); zend_string_release(lcname); RETURN_THROWS(); @@ -3388,7 +3403,10 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ if (class_name) { if ((ce = zend_lookup_class(class_name)) == NULL) { if (!EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(class_name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, class_name); } zend_string_release(class_name); RETURN_THROWS(); @@ -3414,8 +3432,16 @@ static void instantiate_reflection_method(INTERNAL_FUNCTION_PARAMETERS, bool is_ /* do nothing, mptr already set */ } else if ((mptr = zend_hash_str_find_ptr(&ce->function_table, lcname, method_name_len)) == NULL) { efree(lcname); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Method %S::%S() does not exist"; + ALLOCA_FLAG(use_heap); + zend_string *method_name_zstr; + ZSTR_ALLOCA_INIT(method_name_zstr, method_name, method_name_len, use_heap); zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s::%s() does not exist", ZSTR_VAL(ce->name), method_name); + format, ce->name, method_name_zstr); + ZSTR_ALLOCA_FREE(method_name_zstr, use_heap); + RETURN_THROWS(); } efree(lcname); @@ -3919,7 +3945,10 @@ ZEND_METHOD(ReflectionClassConstant, __construct) ce = classname_obj->ce; } else { if ((ce = zend_lookup_class(classname_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, classname_str); RETURN_THROWS(); } } @@ -3928,7 +3957,10 @@ ZEND_METHOD(ReflectionClassConstant, __construct) intern = Z_REFLECTION_P(object); if ((constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), constname)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(constname)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Constant %S::%S does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, ce->name, constname); RETURN_THROWS(); } @@ -4208,7 +4240,10 @@ static void reflection_class_object_ctor(INTERNAL_FUNCTION_PARAMETERS, int is_ob } else { if ((ce = zend_lookup_class(arg_class)) == NULL) { if (!EG(exception)) { - zend_throw_exception_ex(reflection_exception_ptr, -1, "Class \"%s\" does not exist", ZSTR_VAL(arg_class)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, -1, format, arg_class); } RETURN_THROWS(); } @@ -4348,8 +4383,11 @@ ZEND_METHOD(ReflectionClass, getStaticPropertyValue) RETURN_COPY(def_value); } + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Property %S::$%S does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Property %s::$%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + format, ce->name, name); } /* }}} */ @@ -4377,8 +4415,11 @@ ZEND_METHOD(ReflectionClass, setStaticPropertyValue) EG(fake_scope) = old_scope; if (!variable_ptr) { zend_clear_exception(); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class %S does not have a property named %S"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Class %s does not have a property named %s", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + format, ce->name, name); RETURN_THROWS(); } @@ -4642,8 +4683,11 @@ ZEND_METHOD(ReflectionClass, getMethod) } else if ((mptr = zend_hash_find_ptr(&ce->function_table, lc_name)) != NULL) { reflection_method_factory(ce, mptr, NULL, return_value); } else { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Method %S::%S() does not exist"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Method %s::%s() does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + format, ce->name, name); } zend_string_release(lc_name); } @@ -4769,7 +4813,9 @@ ZEND_METHOD(ReflectionClass, getProperty) } } str_name = ZSTR_VAL(name); + bool fully_qualified = false; if ((tmp = strstr(ZSTR_VAL(name), "::")) != NULL) { + fully_qualified = true; classname_len = tmp - ZSTR_VAL(name); classname = zend_string_init(ZSTR_VAL(name), classname_len, 0); str_name_len = ZSTR_LEN(name) - (classname_len + 2); @@ -4786,7 +4832,15 @@ ZEND_METHOD(ReflectionClass, getProperty) zend_string_release_ex(classname, 0); if (!instanceof_function(ce, ce2)) { - zend_throw_exception_ex(reflection_exception_ptr, -1, "Fully qualified property name %s::$%s does not specify a base class of %s", ZSTR_VAL(ce2->name), str_name, ZSTR_VAL(ce->name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Fully qualified property name %S::$%S does not specify a base class of %S"; + ALLOCA_FLAG(use_heap); + zend_string *prop_name_zstr; + ZSTR_ALLOCA_INIT(prop_name_zstr, str_name, str_name_len, use_heap); + zend_throw_exception_ex(reflection_exception_ptr, -1, format, ce2->name, prop_name_zstr, ce->name); + ZSTR_ALLOCA_FREE(prop_name_zstr, use_heap); + RETURN_THROWS(); } ce = ce2; @@ -4799,7 +4853,19 @@ ZEND_METHOD(ReflectionClass, getProperty) return; } } - zend_throw_exception_ex(reflection_exception_ptr, 0, "Property %s::$%s does not exist", ZSTR_VAL(ce->name), str_name); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Property %S::$%S does not exist"; + // Can only use the existing `name` string if it wasn't fully qualified + if (fully_qualified) { + ALLOCA_FLAG(use_heap); + zend_string *prop_name_zstr; + ZSTR_ALLOCA_INIT(prop_name_zstr, str_name, str_name_len, use_heap); + zend_throw_exception_ex(reflection_exception_ptr, 0, format, ce->name, prop_name_zstr); + ZSTR_ALLOCA_FREE(prop_name_zstr, use_heap); + } else { + zend_throw_exception_ex(reflection_exception_ptr, 0, format, ce->name, name); + } } /* }}} */ @@ -5665,7 +5731,10 @@ ZEND_METHOD(ReflectionClass, isSubclassOf) class_ce = argument->ptr; } else { if ((class_ce = zend_lookup_class(class_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(class_str)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, class_str); RETURN_THROWS(); } } @@ -5698,7 +5767,10 @@ ZEND_METHOD(ReflectionClass, implementsInterface) interface_ce = argument->ptr; } else { if ((interface_ce = zend_lookup_class(interface_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Interface \"%s\" does not exist", ZSTR_VAL(interface_str)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Interface \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, interface_str); RETURN_THROWS(); } } @@ -5866,7 +5938,10 @@ ZEND_METHOD(ReflectionProperty, __construct) ce = classname_obj->ce; } else { if ((ce = zend_lookup_class(classname_str)) == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Class \"%s\" does not exist", ZSTR_VAL(classname_str)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Class \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, classname_str); RETURN_THROWS(); } } @@ -5882,7 +5957,10 @@ ZEND_METHOD(ReflectionProperty, __construct) } } if (dynam_prop == 0) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Property %s::$%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Property %S::$%S does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, ce->name, name); RETURN_THROWS(); } } @@ -6244,13 +6322,17 @@ static zend_result reflection_property_check_lazy_compatible( zend_property_info *prop, zend_string *unmangled_name, reflection_object *intern, zend_object *object, const char *method) { - if (!prop) { + if (!prop) { + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Can not use %s on dynamic property %S::$%S"; zend_throw_exception_ex(reflection_exception_ptr, 0, - "Can not use %s on dynamic property %s::$%s", - method, ZSTR_VAL(intern->ce->name), - ZSTR_VAL(unmangled_name)); + format, + method, intern->ce->name, + unmangled_name); return FAILURE; } + // Non-dynamic properties cannot have null bytes so %s is fine if (prop->flags & ZEND_ACC_STATIC) { zend_throw_exception_ex(reflection_exception_ptr, 0, @@ -7569,7 +7651,10 @@ ZEND_METHOD(ReflectionEnum, getCase) zend_class_constant *constant = zend_hash_find_ptr(CE_CONSTANTS_TABLE(ce), name); if (constant == NULL) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Case %s::%s does not exist", ZSTR_VAL(ce->name), ZSTR_VAL(name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Case %S::%S does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, ce->name, name); RETURN_THROWS(); } if (!(ZEND_CLASS_CONST_FLAGS(constant) & ZEND_CLASS_CONST_IS_CASE)) { @@ -7879,7 +7964,10 @@ ZEND_METHOD(ReflectionConstant, __construct) zend_constant *const_ = zend_get_constant_ptr(lc_name); zend_string_release_ex(lc_name, /* persistent */ false); if (!const_) { - zend_throw_exception_ex(reflection_exception_ptr, 0, "Constant \"%s\" does not exist", ZSTR_VAL(name)); + // %S is used for zend_string pointers by smart str printing, but normally + // is for wide character strings and so compilers complain if this is inline + const char *format = "Constant \"%S\" does not exist"; + zend_throw_exception_ex(reflection_exception_ptr, 0, format, name); RETURN_THROWS(); } diff --git a/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_class.phpt b/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_class.phpt new file mode 100644 index 000000000000..cb8ce925e851 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_class.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionClassConstant::__construct() error messages (class name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClassConstant->__construct('foo\x00bar', '') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_constant.phpt b/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_constant.phpt new file mode 100644 index 000000000000..537204a781b4 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClassConstant_construct_constant.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22905: null bytes in ReflectionClassConstant::__construct() error messages (constant name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Constant Demo::foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClassConstant->__construct('Demo', 'foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_construct.phpt b/ext/reflection/tests/gh22905/ReflectionClass_construct.phpt new file mode 100644 index 000000000000..f4575993c631 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_construct.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::__construct() error messages +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->__construct('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_getMethod.phpt b/ext/reflection/tests/gh22905/ReflectionClass_getMethod.phpt new file mode 100644 index 000000000000..27bfbd9072a8 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_getMethod.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::getMethod() error messages +--FILE-- +getMethod("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Method Demo::foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getMethod('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_getProperty.phpt b/ext/reflection/tests/gh22905/ReflectionClass_getProperty.phpt new file mode 100644 index 000000000000..d989daebdebb --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_getProperty.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::getProperty() error messages +--FILE-- +getProperty("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Property Demo::$foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getProperty('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_base.phpt b/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_base.phpt new file mode 100644 index 000000000000..650e9ad189e2 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_base.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::getProperty() (fully qualified, base class) error messages +--FILE-- +getProperty("Base::foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Property Base::$foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getProperty('Base::foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_nobase.phpt b/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_nobase.phpt new file mode 100644 index 000000000000..561a2afc585d --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_getProperty_qualified_nobase.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::getProperty() (fully qualified, non-base class) error messages +--FILE-- +getProperty("Base::foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Fully qualified property name Base::$foo%0bar does not specify a base class of Demo in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getProperty('Base::foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_getStaticPropertyValue.phpt b/ext/reflection/tests/gh22905/ReflectionClass_getStaticPropertyValue.phpt new file mode 100644 index 000000000000..7ded20bedd46 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_getStaticPropertyValue.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::getStaticPropertyValue() error messages +--FILE-- +getStaticPropertyValue("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Property Demo::$foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getStaticPropertyValue('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_implementsInterface.phpt b/ext/reflection/tests/gh22905/ReflectionClass_implementsInterface.phpt new file mode 100644 index 000000000000..b516907dc51e --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_implementsInterface.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::implementsInterface() error messages +--FILE-- +implementsInterface("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Interface "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->implementsInterface('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_isSubclassOf.phpt b/ext/reflection/tests/gh22905/ReflectionClass_isSubclassOf.phpt new file mode 100644 index 000000000000..915426824f3f --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_isSubclassOf.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::isSubclassOf() error messages +--FILE-- +isSubclassOf("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->isSubclassOf('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionClass_setStaticPropertyValue.phpt b/ext/reflection/tests/gh22905/ReflectionClass_setStaticPropertyValue.phpt new file mode 100644 index 000000000000..c450f41cb6ed --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionClass_setStaticPropertyValue.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionClass::setStaticPropertyValue() error messages +--FILE-- +setStaticPropertyValue("foo\0bar", 123); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class Demo does not have a property named foo%0bar in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->setStaticPropertyValue('foo\x00bar', 123) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionConstant_construct.phpt b/ext/reflection/tests/gh22905/ReflectionConstant_construct.phpt new file mode 100644 index 000000000000..62b6024d83d7 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionConstant_construct.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionConstant::__construct() error messages +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Constant "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionConstant->__construct('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionEnum_getCase.phpt b/ext/reflection/tests/gh22905/ReflectionEnum_getCase.phpt new file mode 100644 index 000000000000..3c50da112ef0 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionEnum_getCase.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionEnum::getCase() error messages +--FILE-- +getCase("foo\0bar"); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Case Demo::foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionEnum->getCase('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionFunction_construct.phpt b/ext/reflection/tests/gh22905/ReflectionFunction_construct.phpt new file mode 100644 index 000000000000..a145473c3485 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionFunction_construct.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionFunction::__construct() error messages +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Function foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionFunction->__construct('foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionMethod_construct_class.phpt b/ext/reflection/tests/gh22905/ReflectionMethod_construct_class.phpt new file mode 100644 index 000000000000..fcc39c1209bd --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionMethod_construct_class.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionMethod::__construct() error messages (class name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionMethod->__construct('foo\x00bar', '') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionMethod_construct_method.phpt b/ext/reflection/tests/gh22905/ReflectionMethod_construct_method.phpt new file mode 100644 index 000000000000..1a4ba03cf2d2 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionMethod_construct_method.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22905: null bytes in ReflectionMethod::__construct() error messages (method name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Method Demo::foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionMethod->__construct('Demo', 'foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionMethod_create_method.phpt b/ext/reflection/tests/gh22905/ReflectionMethod_create_method.phpt new file mode 100644 index 000000000000..137106559dcd --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionMethod_create_method.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22905: null bytes in ReflectionMethod::createFromMethodName() error messages (method name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Method Demo::foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionMethod::createFromMethodName('Demo::foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionParameter_construct_class.phpt b/ext/reflection/tests/gh22905/ReflectionParameter_construct_class.phpt new file mode 100644 index 000000000000..6b2b599a1109 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionParameter_construct_class.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionParameter::__construct() error messages (array class name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionParameter->__construct(Array, 0) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionParameter_construct_method.phpt b/ext/reflection/tests/gh22905/ReflectionParameter_construct_method.phpt new file mode 100644 index 000000000000..2158724dd451 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionParameter_construct_method.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22905: null bytes in ReflectionParameter::__construct() error messages (array method name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Method Demo::foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionParameter->__construct(Array, 0) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionParameter_construct_string.phpt b/ext/reflection/tests/gh22905/ReflectionParameter_construct_string.phpt new file mode 100644 index 000000000000..2ac9b8b763d2 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionParameter_construct_string.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionParameter::__construct() error messages (string function) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Function foo%0bar() does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionParameter->__construct('foo\x00bar', 0) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionProperty_construct_class.phpt b/ext/reflection/tests/gh22905/ReflectionProperty_construct_class.phpt new file mode 100644 index 000000000000..a5a785e908ea --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionProperty_construct_class.phpt @@ -0,0 +1,14 @@ +--TEST-- +GH-22905: null bytes in ReflectionProperty::__construct() error messages (class name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Class "foo%0bar" does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionProperty->__construct('foo\x00bar', '') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionProperty_construct_property.phpt b/ext/reflection/tests/gh22905/ReflectionProperty_construct_property.phpt new file mode 100644 index 000000000000..d18f926ecbff --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionProperty_construct_property.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-22905: null bytes in ReflectionProperty::__construct() error messages (property name) +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Property Demo::$foo%0bar does not exist in %s:%d +Stack trace: +#0 %s(%d): ReflectionProperty->__construct('Demo', 'foo\x00bar') +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionProperty_setRawValueWithoutLazyInitialization.phpt b/ext/reflection/tests/gh22905/ReflectionProperty_setRawValueWithoutLazyInitialization.phpt new file mode 100644 index 000000000000..d2d609bcf287 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionProperty_setRawValueWithoutLazyInitialization.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionProperty::setRawValueWithoutLazyInitialization() error messages +--FILE-- + "baz"]; +$r = new ReflectionProperty($o, "foo\0bar"); +$r->setRawValueWithoutLazyInitialization($o, 123); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Can not use setRawValueWithoutLazyInitialization on dynamic property stdClass::$foo%0bar in %s:%d +Stack trace: +#0 %s(%d): ReflectionProperty->setRawValueWithoutLazyInitialization(Object(stdClass), 123) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/ReflectionProperty_skipLazyInitialization.phpt b/ext/reflection/tests/gh22905/ReflectionProperty_skipLazyInitialization.phpt new file mode 100644 index 000000000000..49bad02ab4d7 --- /dev/null +++ b/ext/reflection/tests/gh22905/ReflectionProperty_skipLazyInitialization.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in ReflectionProperty::skipLazyInitialization() error messages +--FILE-- + "baz"]; +$r = new ReflectionProperty($o, "foo\0bar"); +$r->skipLazyInitialization($o); + +?> +--EXPECTF-- +Fatal error: Uncaught ReflectionException: Can not use skipLazyInitialization on dynamic property stdClass::$foo%0bar in %s:%d +Stack trace: +#0 %s(%d): ReflectionProperty->skipLazyInitialization(Object(stdClass)) +#1 {main} + thrown in %s on line %d diff --git a/ext/reflection/tests/gh22905/Reflection_getAttributes.phpt b/ext/reflection/tests/gh22905/Reflection_getAttributes.phpt new file mode 100644 index 000000000000..ea3ec411629f --- /dev/null +++ b/ext/reflection/tests/gh22905/Reflection_getAttributes.phpt @@ -0,0 +1,16 @@ +--TEST-- +GH-22905: null bytes in Reflection*::getAttributes() error messages +--FILE-- +getAttributes("foo\0bar", ReflectionAttribute::IS_INSTANCEOF); + +?> +--EXPECTF-- +Fatal error: Uncaught Error: Class "foo%0bar" not found in %s:%d +Stack trace: +#0 %s(%d): ReflectionClass->getAttributes('foo\x00bar', 2) +#1 {main} + thrown in %s on line %d