From e23c6222da50a2c5828a03ad701cd3351b13590d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Tue, 23 Sep 2025 09:19:56 +0200 Subject: [PATCH 1/5] uri: Clean up naming of remaining public symbols (#19917) * uri: Rename `uri_object_t` to `php_uri_object` * uri: Rename `uri_(read|write)_component_*` to `php_uri_property_(read|write)_*_helper` * uri: Rename `URI_SERIALIZED_PROPERTY_NAME` to `PHP_URI_SERIALIZE_URI_FIELD_NAME` * uri: Rename `uri_internal_t` to `php_uri_internal` * uri: Use proper `php_uri_ce_` prefix for all CEs * uri: Make the object handlers `static` and remove them from the header --- ext/openssl/xp_ssl.c | 2 +- ext/uri/php_uri.c | 239 +++++++++++++++-------------- ext/uri/php_uri.h | 22 +-- ext/uri/php_uri_common.c | 24 +-- ext/uri/php_uri_common.h | 46 +++--- ext/uri/uri_parser_php_parse_url.c | 2 +- ext/uri/uri_parser_rfc3986.c | 46 +++--- ext/uri/uri_parser_whatwg.c | 14 +- ext/zend_test/test.c | 2 +- 9 files changed, 198 insertions(+), 199 deletions(-) diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 23f37355af568..6a4f8d7575c1a 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -2640,7 +2640,7 @@ static char *php_openssl_get_url_name(const char *resourcename, return NULL; } - uri_internal_t *internal_uri = php_uri_parse(uri_parser, resourcename, resourcenamelen, true); + php_uri_internal *internal_uri = php_uri_parse(uri_parser, resourcename, resourcenamelen, true); if (internal_uri == NULL) { return NULL; } diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 10660888781de..b15114d09cc22 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -32,17 +32,18 @@ #include "php_uri_arginfo.h" #include "uriparser/UriBase.h" -zend_class_entry *uri_rfc3986_uri_ce; -zend_object_handlers uri_rfc3986_uri_object_handlers; -zend_class_entry *uri_whatwg_url_ce; -zend_object_handlers uri_whatwg_uri_object_handlers; -zend_class_entry *uri_comparison_mode_ce; -zend_class_entry *uri_exception_ce; -zend_class_entry *uri_error_ce; -zend_class_entry *uri_invalid_uri_exception_ce; -zend_class_entry *uri_whatwg_invalid_url_exception_ce; -zend_class_entry *uri_whatwg_url_validation_error_type_ce; -zend_class_entry *uri_whatwg_url_validation_error_ce; +zend_class_entry *php_uri_ce_rfc3986_uri; +zend_class_entry *php_uri_ce_whatwg_url; +zend_class_entry *php_uri_ce_comparison_mode; +zend_class_entry *php_uri_ce_exception; +zend_class_entry *php_uri_ce_error; +zend_class_entry *php_uri_ce_invalid_uri_exception; +zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; +zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; +zend_class_entry *php_uri_ce_whatwg_url_validation_error; + +static zend_object_handlers object_handlers_rfc3986_uri; +static zend_object_handlers object_handlers_whatwg_uri; static const zend_module_dep uri_deps[] = { ZEND_MOD_REQUIRED("lexbor") @@ -51,7 +52,7 @@ static const zend_module_dep uri_deps[] = { static zend_array uri_parsers; -static HashTable *uri_get_debug_properties(uri_object_t *object) +static HashTable *uri_get_debug_properties(php_uri_object *object) { const HashTable *std_properties = zend_std_get_properties(&object->std); HashTable *result = zend_array_dup(std_properties); @@ -108,9 +109,9 @@ PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name) return zend_hash_find_ptr(&uri_parsers, uri_parser_name); } -ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent) +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri_internal *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent) { - uri_internal_t *internal_uri = emalloc(sizeof(*internal_uri)); + php_uri_internal *internal_uri = emalloc(sizeof(*internal_uri)); internal_uri->parser = uri_parser; internal_uri->uri = uri_parser->parse(uri_str, uri_str_len, NULL, NULL, silent); @@ -122,47 +123,47 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser return internal_uri; } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.scheme.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.username.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.password.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.host.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.port.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.path.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.query.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv) +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv) { return internal_uri->parser->property_handler.fragment.read(internal_uri->uri, read_mode, zv); } -ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(uri_internal_t *internal_uri) +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(php_uri_internal *internal_uri) { internal_uri->parser->destroy(internal_uri->uri); internal_uri->uri = NULL; @@ -173,7 +174,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(uri_internal_t *internal_uri) ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct( const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, php_uri_component_read_mode read_mode, bool silent ) { - uri_internal_t *uri_internal = php_uri_parse(uri_parser, uri_str, uri_str_len, silent); + php_uri_internal *uri_internal = php_uri_parse(uri_parser, uri_str, uri_str_len, silent); if (uri_internal == NULL) { return NULL; } @@ -314,11 +315,11 @@ static zend_result pass_errors_by_ref_and_free(zval *errors_zv, zval *errors) } ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri( - INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const uri_object_t *base_url_object, + INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const php_uri_object *base_url_object, bool should_throw, bool should_update_this_object, zval *errors_zv ) { - uri_object_t *uri_object; + php_uri_object *uri_object; if (should_update_this_object) { uri_object = Z_URI_OBJECT_P(ZEND_THIS); if (uri_object->uri != NULL) { @@ -377,11 +378,11 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor ZEND_PARSE_PARAMETERS_START(1, 2) Z_PARAM_PATH_STR(uri_str) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_rfc3986_uri_ce) + Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, php_uri_ce_rfc3986_uri) ZEND_PARSE_PARAMETERS_END(); php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, - uri_str, base_url_object ? uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, NULL); + uri_str, base_url_object ? php_uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, NULL); } static bool is_list_of_whatwg_validation_errors(const HashTable *array) @@ -397,7 +398,7 @@ static bool is_list_of_whatwg_validation_errors(const HashTable *array) return false; } - if (!instanceof_function(Z_OBJCE_P(val), uri_whatwg_url_validation_error_ce)) { + if (!instanceof_function(Z_OBJCE_P(val), php_uri_ce_whatwg_url_validation_error)) { return false; } } ZEND_HASH_FOREACH_END(); @@ -437,14 +438,14 @@ PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct) if (errors == NULL) { zval tmp; ZVAL_EMPTY_ARRAY(&tmp); - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); + zend_update_property(php_uri_ce_whatwg_invalid_url_exception, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), &tmp); } else { if (!is_list_of_whatwg_validation_errors(Z_ARR_P(errors))) { - zend_argument_value_error(2, "must be a list of %s", ZSTR_VAL(uri_whatwg_url_validation_error_ce->name)); + zend_argument_value_error(2, "must be a list of %s", ZSTR_VAL(php_uri_ce_whatwg_url_validation_error->name)); RETURN_THROWS(); } - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); + zend_update_property(php_uri_ce_whatwg_invalid_url_exception, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors); } if (EG(exception)) { RETURN_THROWS(); @@ -459,23 +460,23 @@ PHP_METHOD(Uri_WhatWg_UrlValidationError, __construct) ZEND_PARSE_PARAMETERS_START(3, 3) Z_PARAM_STR(context) - Z_PARAM_OBJECT_OF_CLASS(type, uri_whatwg_url_validation_error_type_ce) + Z_PARAM_OBJECT_OF_CLASS(type, php_uri_ce_whatwg_url_validation_error_type) Z_PARAM_BOOL(failure) ZEND_PARSE_PARAMETERS_END(); - zend_update_property_str(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); + zend_update_property_str(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZEND_STRL("context"), context); if (EG(exception)) { RETURN_THROWS(); } - zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); + zend_update_property_ex(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZSTR_KNOWN(ZEND_STR_TYPE), type); if (EG(exception)) { RETURN_THROWS(); } zval failure_zv; ZVAL_BOOL(&failure_zv, failure); - zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); + zend_update_property(php_uri_ce_whatwg_url_validation_error, Z_OBJ_P(ZEND_THIS), ZEND_STRL("failure"), &failure_zv); if (EG(exception)) { RETURN_THROWS(); } @@ -490,12 +491,12 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor) ZEND_PARSE_PARAMETERS_START(1, 3) Z_PARAM_PATH_STR(uri_str) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, uri_whatwg_url_ce) + Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, php_uri_ce_whatwg_url) Z_PARAM_ZVAL(errors) ZEND_PARSE_PARAMETERS_END(); php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, - uri_str, base_url_object ? uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, errors); + uri_str, base_url_object ? php_uri_object_from_obj(base_url_object) : NULL, is_constructor, is_constructor, errors); } PHP_METHOD(Uri_WhatWg_Url, parse) @@ -510,24 +511,24 @@ PHP_METHOD(Uri_WhatWg_Url, __construct) PHP_METHOD(Uri_Rfc3986_Uri, getScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withScheme) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); } static void rfc3986_userinfo_read(INTERNAL_FUNCTION_PARAMETERS, php_uri_component_read_mode read_mode) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(uri_object->uri != NULL); if (UNEXPECTED(php_uri_parser_rfc3986_userinfo_read(uri_object->uri, read_mode, return_value) == FAILURE)) { @@ -561,7 +562,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, withUserInfo) ZVAL_STR(&zv, value); } - uri_object_t *old_uri_object = uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); + php_uri_object *old_uri_object = php_uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); ZEND_ASSERT(old_uri_object->uri != NULL); zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std); @@ -573,7 +574,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, withUserInfo) * case of an exception being thrown. */ RETVAL_OBJ(new_object); - uri_object_t *new_uri_object = uri_object_from_obj(new_object); + php_uri_object *new_uri_object = php_uri_object_from_obj(new_object); ZEND_ASSERT(new_uri_object->uri != NULL); if (UNEXPECTED(php_uri_parser_rfc3986_userinfo_write(new_uri_object->uri, &zv, NULL) == FAILURE)) { @@ -583,102 +584,102 @@ PHP_METHOD(Uri_Rfc3986_Uri, withUserInfo) PHP_METHOD(Uri_Rfc3986_Uri, getUsername) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawUsername) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, getPassword) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawPassword) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, getHost) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawHost) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withHost) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST); } PHP_METHOD(Uri_Rfc3986_Uri, getPort) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withPort) { - uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT); + php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PORT); } PHP_METHOD(Uri_Rfc3986_Uri, getPath) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawPath) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withPath) { - uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH); + php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PATH); } PHP_METHOD(Uri_Rfc3986_Uri, getQuery) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawQuery) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withQuery) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_QUERY); } PHP_METHOD(Uri_Rfc3986_Uri, getFragment) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_Rfc3986_Uri, getRawFragment) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_RAW); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_RAW); } PHP_METHOD(Uri_Rfc3986_Uri, withFragment) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT); } -static void throw_cannot_recompose_uri_to_string(uri_object_t *object) +static void throw_cannot_recompose_uri_to_string(php_uri_object *object) { - zend_throw_exception_ex(uri_error_ce, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->std.ce->name)); + zend_throw_exception_ex(php_uri_ce_error, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->std.ce->name)); } -static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, uri_object_t *that_object, zend_object *comparison_mode) +static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, php_uri_object *that_object, zend_object *comparison_mode) { - uri_object_t *this_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *this_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(this_object->uri != NULL); ZEND_ASSERT(that_object->uri != NULL); @@ -722,19 +723,19 @@ PHP_METHOD(Uri_Rfc3986_Uri, equals) zend_object *comparison_mode = NULL; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJ_OF_CLASS(that_object, uri_rfc3986_uri_ce) + Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_rfc3986_uri) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce) + Z_PARAM_OBJ_OF_CLASS(comparison_mode, php_uri_ce_comparison_mode) ZEND_PARSE_PARAMETERS_END(); - uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_object_from_obj(that_object), comparison_mode); + uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode); } PHP_METHOD(Uri_Rfc3986_Uri, toRawString) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(uri_object->uri != NULL); zend_string *uri_str = uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false); @@ -750,7 +751,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, toString) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(uri_object->uri != NULL); zend_string *uri_str = uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_NORMALIZED_ASCII, false); @@ -778,7 +779,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, __serialize) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(uri_object->uri != NULL); /* Serialize state: "uri" key in the first array */ @@ -794,7 +795,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, __serialize) zval arr; array_init(&arr); - zend_hash_str_add_new(Z_ARRVAL(arr), URI_SERIALIZED_PROPERTY_NAME, sizeof(URI_SERIALIZED_PROPERTY_NAME) - 1, &tmp); + zend_hash_str_add_new(Z_ARRVAL(arr), PHP_URI_SERIALIZE_URI_FIELD_NAME, sizeof(PHP_URI_SERIALIZE_URI_FIELD_NAME) - 1, &tmp); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); /* Serialize regular properties: second array */ @@ -811,7 +812,7 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS) Z_PARAM_ARRAY_HT(data) ZEND_PARSE_PARAMETERS_END(); - uri_object_t *uri_object = uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); + php_uri_object *uri_object = php_uri_object_from_obj(Z_OBJ_P(ZEND_THIS)); if (uri_object->uri != NULL) { /* Intentionally throw two exceptions for proper chaining. */ zend_throw_error(NULL, "Cannot modify readonly object of class %s", ZSTR_VAL(uri_object->std.ce->name)); @@ -838,7 +839,7 @@ static void uri_unserialize(INTERNAL_FUNCTION_PARAMETERS) RETURN_THROWS(); } - zval *uri_zv = zend_hash_str_find_ind(Z_ARRVAL_P(arr), ZEND_STRL(URI_SERIALIZED_PROPERTY_NAME)); + zval *uri_zv = zend_hash_str_find_ind(Z_ARRVAL_P(arr), ZEND_STRL(PHP_URI_SERIALIZE_URI_FIELD_NAME)); if (uri_zv == NULL || Z_TYPE_P(uri_zv) != IS_STRING) { zend_throw_exception_ex(NULL, 0, "Invalid serialization data for %s object", ZSTR_VAL(uri_object->std.ce->name)); RETURN_THROWS(); @@ -873,44 +874,44 @@ PHP_METHOD(Uri_Rfc3986_Uri, __debugInfo) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); RETURN_ARR(uri_get_debug_properties(uri_object)); } PHP_METHOD(Uri_WhatWg_Url, getScheme) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_WhatWg_Url, withScheme) { - uri_write_component_str(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); + php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); } PHP_METHOD(Uri_WhatWg_Url, withUsername) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME); } PHP_METHOD(Uri_WhatWg_Url, withPassword) { - uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD); + php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_PASSWORD); } PHP_METHOD(Uri_WhatWg_Url, getAsciiHost) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); } PHP_METHOD(Uri_WhatWg_Url, getUnicodeHost) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } PHP_METHOD(Uri_WhatWg_Url, getFragment) { - uri_read_component(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); + php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } PHP_METHOD(Uri_WhatWg_Url, equals) @@ -919,12 +920,12 @@ PHP_METHOD(Uri_WhatWg_Url, equals) zend_object *comparison_mode = NULL; ZEND_PARSE_PARAMETERS_START(1, 2) - Z_PARAM_OBJ_OF_CLASS(that_object, uri_whatwg_url_ce) + Z_PARAM_OBJ_OF_CLASS(that_object, php_uri_ce_whatwg_url) Z_PARAM_OPTIONAL - Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce) + Z_PARAM_OBJ_OF_CLASS(comparison_mode, php_uri_ce_comparison_mode) ZEND_PARSE_PARAMETERS_END(); - uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_object_from_obj(that_object), comparison_mode); + uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, php_uri_object_from_obj(that_object), comparison_mode); } PHP_METHOD(Uri_WhatWg_Url, toUnicodeString) @@ -932,7 +933,7 @@ PHP_METHOD(Uri_WhatWg_Url, toUnicodeString) ZEND_PARSE_PARAMETERS_NONE(); zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_object_t *uri_object = uri_object_from_obj(this_object); + php_uri_object *uri_object = php_uri_object_from_obj(this_object); ZEND_ASSERT(uri_object->uri != NULL); RETURN_STR(uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_UNICODE, false)); @@ -943,7 +944,7 @@ PHP_METHOD(Uri_WhatWg_Url, toAsciiString) ZEND_PARSE_PARAMETERS_NONE(); zend_object *this_object = Z_OBJ_P(ZEND_THIS); - uri_object_t *uri_object = uri_object_from_obj(this_object); + php_uri_object *uri_object = php_uri_object_from_obj(this_object); ZEND_ASSERT(uri_object->uri != NULL); RETURN_STR(uri_object->parser->to_string(uri_object->uri, PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, false)); @@ -968,7 +969,7 @@ PHP_METHOD(Uri_WhatWg_Url, __serialize) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *this_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *this_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(this_object->uri != NULL); /* Serialize state: "uri" key in the first array */ @@ -984,7 +985,7 @@ PHP_METHOD(Uri_WhatWg_Url, __serialize) zval arr; array_init(&arr); - zend_hash_str_add_new(Z_ARRVAL(arr), ZEND_STRL(URI_SERIALIZED_PROPERTY_NAME), &tmp); + zend_hash_str_add_new(Z_ARRVAL(arr), ZEND_STRL(PHP_URI_SERIALIZE_URI_FIELD_NAME), &tmp); zend_hash_next_index_insert(Z_ARRVAL_P(return_value), &arr); /* Serialize regular properties: second array */ @@ -1002,14 +1003,14 @@ PHP_METHOD(Uri_WhatWg_Url, __debugInfo) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); RETURN_ARR(uri_get_debug_properties(uri_object)); } -PHPAPI uri_object_t *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser) +PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser) { - uri_object_t *uri_object = zend_object_alloc(sizeof(*uri_object), class_type); + php_uri_object *uri_object = zend_object_alloc(sizeof(*uri_object), class_type); zend_object_std_init(&uri_object->std, class_type); object_properties_init(&uri_object->std, class_type); @@ -1032,7 +1033,7 @@ static zend_object *php_uri_object_create_whatwg(zend_class_entry *ce) PHPAPI void php_uri_object_handler_free(zend_object *object) { - uri_object_t *uri_object = uri_object_from_obj(object); + php_uri_object *uri_object = php_uri_object_from_obj(object); uri_object->parser->destroy(uri_object->uri); zend_object_std_dtor(&uri_object->std); @@ -1040,11 +1041,11 @@ PHPAPI void php_uri_object_handler_free(zend_object *object) PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object) { - uri_object_t *uri_object = uri_object_from_obj(object); + php_uri_object *uri_object = php_uri_object_from_obj(object); ZEND_ASSERT(uri_object->uri != NULL); - uri_object_t *new_uri_object = uri_object_from_obj(object->ce->create_object(object->ce)); + php_uri_object *new_uri_object = php_uri_object_from_obj(object->ce->create_object(object->ce)); ZEND_ASSERT(new_uri_object->parser == uri_object->parser); void *uri = uri_object->parser->clone(uri_object->uri); @@ -1076,29 +1077,29 @@ PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser) static PHP_MINIT_FUNCTION(uri) { - uri_rfc3986_uri_ce = register_class_Uri_Rfc3986_Uri(); - uri_rfc3986_uri_ce->create_object = php_uri_object_create_rfc3986; - uri_rfc3986_uri_ce->default_object_handlers = &uri_rfc3986_uri_object_handlers; - memcpy(&uri_rfc3986_uri_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - uri_rfc3986_uri_object_handlers.offset = XtOffsetOf(uri_object_t, std); - uri_rfc3986_uri_object_handlers.free_obj = php_uri_object_handler_free; - uri_rfc3986_uri_object_handlers.clone_obj = php_uri_object_handler_clone; - - uri_whatwg_url_ce = register_class_Uri_WhatWg_Url(); - uri_whatwg_url_ce->create_object = php_uri_object_create_whatwg; - uri_whatwg_url_ce->default_object_handlers = &uri_whatwg_uri_object_handlers; - memcpy(&uri_whatwg_uri_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); - uri_whatwg_uri_object_handlers.offset = XtOffsetOf(uri_object_t, std); - uri_whatwg_uri_object_handlers.free_obj = php_uri_object_handler_free; - uri_whatwg_uri_object_handlers.clone_obj = php_uri_object_handler_clone; - - uri_comparison_mode_ce = register_class_Uri_UriComparisonMode(); - uri_exception_ce = register_class_Uri_UriException(zend_ce_exception); - uri_error_ce = register_class_Uri_UriError(zend_ce_error); - uri_invalid_uri_exception_ce = register_class_Uri_InvalidUriException(uri_exception_ce); - uri_whatwg_invalid_url_exception_ce = register_class_Uri_WhatWg_InvalidUrlException(uri_invalid_uri_exception_ce); - uri_whatwg_url_validation_error_ce = register_class_Uri_WhatWg_UrlValidationError(); - uri_whatwg_url_validation_error_type_ce = register_class_Uri_WhatWg_UrlValidationErrorType(); + php_uri_ce_rfc3986_uri = register_class_Uri_Rfc3986_Uri(); + php_uri_ce_rfc3986_uri->create_object = php_uri_object_create_rfc3986; + php_uri_ce_rfc3986_uri->default_object_handlers = &object_handlers_rfc3986_uri; + memcpy(&object_handlers_rfc3986_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + object_handlers_rfc3986_uri.offset = XtOffsetOf(php_uri_object, std); + object_handlers_rfc3986_uri.free_obj = php_uri_object_handler_free; + object_handlers_rfc3986_uri.clone_obj = php_uri_object_handler_clone; + + php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url(); + php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg; + php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri; + memcpy(&object_handlers_whatwg_uri, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + object_handlers_whatwg_uri.offset = XtOffsetOf(php_uri_object, std); + object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free; + object_handlers_whatwg_uri.clone_obj = php_uri_object_handler_clone; + + php_uri_ce_comparison_mode = register_class_Uri_UriComparisonMode(); + php_uri_ce_exception = register_class_Uri_UriException(zend_ce_exception); + php_uri_ce_error = register_class_Uri_UriError(zend_ce_error); + php_uri_ce_invalid_uri_exception = register_class_Uri_InvalidUriException(php_uri_ce_exception); + php_uri_ce_whatwg_invalid_url_exception = register_class_Uri_WhatWg_InvalidUrlException(php_uri_ce_invalid_uri_exception); + php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError(); + php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType(); zend_hash_init(&uri_parsers, 4, NULL, NULL, true); diff --git a/ext/uri/php_uri.h b/ext/uri/php_uri.h index 9cfe6dce1ab97..1ec3617b096ca 100644 --- a/ext/uri/php_uri.h +++ b/ext/uri/php_uri.h @@ -51,7 +51,7 @@ PHPAPI zend_result php_uri_parser_register(const php_uri_parser *uri_parser); */ PHPAPI const php_uri_parser *php_uri_get_parser(zend_string *uri_parser_name); -ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent); +ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri_internal *php_uri_parse(const php_uri_parser *uri_parser, const char *uri_str, size_t uri_str_len, bool silent); /** * Retrieves the scheme component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -66,7 +66,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI uri_internal_t *php_uri_parse(const php_uri_parser * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the username component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -81,7 +81,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_scheme(const uri_internal_ * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the password component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -96,7 +96,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_username(const uri_interna * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the host component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -111,7 +111,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_password(const uri_interna * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the port component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -126,7 +126,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_host(const uri_internal_t * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_LONG or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the path component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -141,7 +141,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_port(const uri_internal_t * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the query component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -156,7 +156,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_path(const uri_internal_t * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Retrieves the fragment component based on the read_mode and passes it to the zv ZVAL in case of success. @@ -171,14 +171,14 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_query(const uri_internal_t * @param zv The output parameter containing the retrieved component as a ZVAL (either IS_STRING or IS_NULL). * @return SUCCESS in case of success, FAILURE otherwise. */ -ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const uri_internal_t *internal_uri, php_uri_component_read_mode read_mode, zval *zv); +ZEND_ATTRIBUTE_NONNULL PHPAPI zend_result php_uri_get_fragment(const php_uri_internal *internal_uri, php_uri_component_read_mode read_mode, zval *zv); /** * Frees the uri member within the provided internal URI. * * @param internal_uri The internal URI */ -ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(uri_internal_t *internal_uri); +ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_free(php_uri_internal *internal_uri); /** * Creates a new php_uri struct containing all the URI components. The components are retrieved based on the read_mode parameter. @@ -207,7 +207,7 @@ ZEND_ATTRIBUTE_NONNULL PHPAPI php_uri *php_uri_parse_to_struct( ZEND_ATTRIBUTE_NONNULL PHPAPI void php_uri_struct_free(php_uri *uri); ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri( - INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const uri_object_t *base_url_object, + INTERNAL_FUNCTION_PARAMETERS, const zend_string *uri_str, const php_uri_object *base_url_object, bool should_throw, bool should_update_this_object, zval *errors_zv ); diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index 282c45d7824c4..780cc95074159 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -42,24 +42,24 @@ static zend_string *get_known_string_by_property_name(php_uri_property_name prop } } -void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode) +void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode) { ZEND_PARSE_PARAMETERS_NONE(); - uri_object_t *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(uri_object->uri != NULL); const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(uri_object->parser, property_name); if (UNEXPECTED(property_handler->read(uri_object->uri, component_read_mode, return_value) == FAILURE)) { - zend_throw_exception_ex(uri_error_ce, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); + zend_throw_exception_ex(php_uri_ce_error, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); RETURN_THROWS(); } } -static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv) +static void php_uri_property_write_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, zval *property_zv) { - uri_object_t *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS); + php_uri_object *old_uri_object = Z_URI_OBJECT_P(ZEND_THIS); ZEND_ASSERT(old_uri_object->uri != NULL); zend_object *new_object = old_uri_object->std.handlers->clone_obj(&old_uri_object->std); @@ -73,7 +73,7 @@ static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, php_uri_propert const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(old_uri_object->parser, property_name); - uri_object_t *new_uri_object = uri_object_from_obj(new_object); + php_uri_object *new_uri_object = php_uri_object_from_obj(new_object); ZEND_ASSERT(new_uri_object->uri != NULL); if (UNEXPECTED(property_handler->write == NULL)) { zend_readonly_property_modification_error_ex(ZSTR_VAL(old_uri_object->std.ce->name), @@ -91,7 +91,7 @@ static void uri_write_component_ex(INTERNAL_FUNCTION_PARAMETERS, php_uri_propert ZEND_ASSERT(Z_ISUNDEF(errors)); } -void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) +void php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_string *value; @@ -102,10 +102,10 @@ void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name zval zv; ZVAL_STR(&zv, value); - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } -void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) +void php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_string *value; @@ -120,10 +120,10 @@ void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_prope ZVAL_STR(&zv, value); } - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } -void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) +void php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name) { zend_long value; bool value_is_null; @@ -139,5 +139,5 @@ void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_prop ZVAL_LONG(&zv, value); } - uri_write_component_ex(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); + php_uri_property_write_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, property_name, &zv); } diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 52d80a290bb4d..109236879ae7f 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -17,17 +17,15 @@ #ifndef PHP_URI_COMMON_H #define PHP_URI_COMMON_H -extern zend_class_entry *uri_rfc3986_uri_ce; -extern zend_object_handlers uri_rfc3986_uri_object_handlers; -extern zend_class_entry *uri_whatwg_url_ce; -extern zend_object_handlers uri_whatwg_uri_object_handlers; -extern zend_class_entry *uri_comparison_mode_ce; -extern zend_class_entry *uri_exception_ce; -extern zend_class_entry *uri_error_ce; -extern zend_class_entry *uri_invalid_uri_exception_ce; -extern zend_class_entry *uri_whatwg_invalid_url_exception_ce; -extern zend_class_entry *uri_whatwg_url_validation_error_type_ce; -extern zend_class_entry *uri_whatwg_url_validation_error_ce; +extern zend_class_entry *php_uri_ce_rfc3986_uri; +extern zend_class_entry *php_uri_ce_whatwg_url; +extern zend_class_entry *php_uri_ce_comparison_mode; +extern zend_class_entry *php_uri_ce_exception; +extern zend_class_entry *php_uri_ce_error; +extern zend_class_entry *php_uri_ce_invalid_uri_exception; +extern zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; +extern zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; +extern zend_class_entry *php_uri_ce_whatwg_url_validation_error; typedef enum php_uri_recomposition_mode { PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, @@ -137,31 +135,31 @@ typedef struct php_uri_parser { } property_handler; } php_uri_parser; -typedef struct uri_internal_t { +typedef struct php_uri_internal { const php_uri_parser *parser; void *uri; -} uri_internal_t; +} php_uri_internal; -typedef struct uri_object_t { +typedef struct php_uri_object { const php_uri_parser *parser; void *uri; zend_object std; -} uri_object_t; +} php_uri_object; -static inline uri_object_t *uri_object_from_obj(zend_object *object) { - return (uri_object_t*)((char*)(object) - XtOffsetOf(uri_object_t, std)); +static inline php_uri_object *php_uri_object_from_obj(zend_object *object) { + return (php_uri_object*)((char*)(object) - XtOffsetOf(php_uri_object, std)); } -#define Z_URI_OBJECT_P(zv) uri_object_from_obj(Z_OBJ_P((zv))) +#define Z_URI_OBJECT_P(zv) php_uri_object_from_obj(Z_OBJ_P((zv))) -PHPAPI uri_object_t *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser); +PHPAPI php_uri_object *php_uri_object_create(zend_class_entry *class_type, const php_uri_parser *parser); PHPAPI void php_uri_object_handler_free(zend_object *object); PHPAPI zend_object *php_uri_object_handler_clone(zend_object *object); #define PHP_URI_PARSER_RFC3986 "Uri\\Rfc3986\\Uri" #define PHP_URI_PARSER_WHATWG "Uri\\WhatWg\\Url" #define PHP_URI_PARSER_PHP_PARSE_URL "parse_url" -#define URI_SERIALIZED_PROPERTY_NAME "uri" +#define PHP_URI_SERIALIZE_URI_FIELD_NAME "uri" static inline const php_uri_property_handler *php_uri_parser_property_handler_by_name(const php_uri_parser *parser, php_uri_property_name property_name) { @@ -186,9 +184,9 @@ static inline const php_uri_property_handler *php_uri_parser_property_handler_by } } -void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode); -void uri_write_component_str(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); -void uri_write_component_str_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); -void uri_write_component_long_or_null(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); +void php_uri_property_read_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name, php_uri_component_read_mode component_read_mode); +void php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); +void php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); +void php_uri_property_write_long_or_null_helper(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name property_name); #endif diff --git a/ext/uri/uri_parser_php_parse_url.c b/ext/uri/uri_parser_php_parse_url.c index b8b3c8ae7d6d4..a185068a0392e 100644 --- a/ext/uri/uri_parser_php_parse_url.c +++ b/ext/uri/uri_parser_php_parse_url.c @@ -148,7 +148,7 @@ static void *uri_parser_php_parse_url_parse(const char *uri_str, size_t uri_str_ php_url *url = php_url_parse_ex2(uri_str, uri_str_len, &has_port); if (url == NULL && !silent) { - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified URI is malformed", 0); } return url; diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 0efae6d9db8c2..24dd4e1947b2b 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -132,11 +132,11 @@ static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, zval *value, z case URI_SUCCESS: return SUCCESS; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified scheme is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified scheme is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the scheme", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the scheme", 0); return FAILURE; } } @@ -169,14 +169,14 @@ zend_result php_uri_parser_rfc3986_userinfo_write(void *uri, zval *value, zval * case URI_SUCCESS: return SUCCESS; case URI_ERROR_SETUSERINFO_HOST_NOT_SET: - zend_throw_exception(uri_invalid_uri_exception_ce, "Cannot set a userinfo without having a host", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "Cannot set a userinfo without having a host", 0); return FAILURE; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified userinfo is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified userinfo is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the userinfo", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the userinfo", 0); return FAILURE; } } @@ -261,17 +261,17 @@ static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zva case URI_SUCCESS: return SUCCESS; case URI_ERROR_SETHOST_PORT_SET: - zend_throw_exception(uri_invalid_uri_exception_ce, "Cannot remove the host from a URI that has a port", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "Cannot remove the host from a URI that has a port", 0); return FAILURE; case URI_ERROR_SETHOST_USERINFO_SET: - zend_throw_exception(uri_invalid_uri_exception_ce, "Cannot remove the host from a URI that has a userinfo", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "Cannot remove the host from a URI that has a userinfo", 0); return FAILURE; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified host is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified host is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the host", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the host", 0); return FAILURE; } } @@ -324,14 +324,14 @@ static zend_result php_uri_parser_rfc3986_port_write(void *uri, zval *value, zva case URI_SUCCESS: return SUCCESS; case URI_ERROR_SETPORT_HOST_NOT_SET: - zend_throw_exception(uri_invalid_uri_exception_ce, "Cannot set a port without having a host", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "Cannot set a port without having a host", 0); return FAILURE; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified port is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified port is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the port", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the port", 0); return FAILURE; } } @@ -379,11 +379,11 @@ static zend_result php_uri_parser_rfc3986_path_write(void *uri, zval *value, zva case URI_SUCCESS: return SUCCESS; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified path is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified path is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the path", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the path", 0); return FAILURE; } } @@ -416,11 +416,11 @@ static zend_result php_uri_parser_rfc3986_query_write(void *uri, zval *value, zv case URI_SUCCESS: return SUCCESS; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified query is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified query is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the query", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the query", 0); return FAILURE; } } @@ -453,11 +453,11 @@ static zend_result php_uri_parser_rfc3986_fragment_write(void *uri, zval *value, case URI_SUCCESS: return SUCCESS; case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified fragment is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified fragment is malformed", 0); return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to update the fragment", 0); + zend_throw_exception(php_uri_ce_error, "Failed to update the fragment", 0); return FAILURE; } } @@ -480,11 +480,11 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str if (!silent) { switch (result) { case URI_ERROR_SYNTAX: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified URI is malformed", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified URI is malformed", 0); break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to parse the specified URI", 0); + zend_throw_exception(php_uri_ce_error, "Failed to parse the specified URI", 0); break; } } @@ -502,11 +502,11 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str if (!silent) { switch (result) { case URI_ERROR_ADDBASE_REL_BASE: - zend_throw_exception(uri_invalid_uri_exception_ce, "The specified base URI must be absolute", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The specified base URI must be absolute", 0); break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_error_ce, "Failed to resolve the specified URI against the base URI", 0); + zend_throw_exception(php_uri_ce_error, "Failed to resolve the specified URI against the base URI", 0); break; } } @@ -525,7 +525,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str if (has_text_range(&uri.portText) && get_text_range_length(&uri.portText) > 0) { if (port_str_to_zend_long_checked(uri.portText.first, get_text_range_length(&uri.portText)) == -1) { if (!silent) { - zend_throw_exception(uri_invalid_uri_exception_ce, "The port is out of range", 0); + zend_throw_exception(php_uri_ce_invalid_uri_exception, "The port is out of range", 0); } goto fail; diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c index 99adaabc5b387..fab228a2d70cf 100644 --- a/ext/uri/uri_parser_whatwg.c +++ b/ext/uri/uri_parser_whatwg.c @@ -73,8 +73,8 @@ static const char *fill_errors(zval *errors) lexbor_plog_entry_t *lxb_error; while ((lxb_error = lexbor_array_obj_pop(&lexbor_parser.log->list)) != NULL) { zval error; - object_init_ex(&error, uri_whatwg_url_validation_error_ce); - zend_update_property_string(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("context"), (const char *) lxb_error->data); + object_init_ex(&error, php_uri_ce_whatwg_url_validation_error); + zend_update_property_string(php_uri_ce_whatwg_url_validation_error, Z_OBJ(error), ZEND_STRL("context"), (const char *) lxb_error->data); const char *error_str; zval failure; @@ -199,10 +199,10 @@ static const char *fill_errors(zval *errors) } zval error_type; - ZVAL_OBJ(&error_type, zend_enum_get_case_cstr(uri_whatwg_url_validation_error_type_ce, error_str)); - zend_update_property_ex(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZSTR_KNOWN(ZEND_STR_TYPE), &error_type); + ZVAL_OBJ(&error_type, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_validation_error_type, error_str)); + zend_update_property_ex(php_uri_ce_whatwg_url_validation_error, Z_OBJ(error), ZSTR_KNOWN(ZEND_STR_TYPE), &error_type); - zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("failure"), &failure); + zend_update_property(php_uri_ce_whatwg_url_validation_error, Z_OBJ(error), ZEND_STRL("failure"), &failure); if (Z_TYPE(failure) == IS_TRUE) { result = error_str; @@ -219,7 +219,7 @@ static void throw_invalid_url_exception_during_write(zval *errors, const char *c zval err; const char *reason = fill_errors(&err); zend_object *exception = zend_throw_exception_ex( - uri_whatwg_invalid_url_exception_ce, + php_uri_ce_whatwg_invalid_url_exception, 0, "The specified %s is malformed%s%s%s", component, @@ -565,7 +565,7 @@ lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_le zval err; const char *reason = fill_errors(&err); if (url == NULL && !silent) { - zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); + zend_object *exception = zend_throw_exception_ex(php_uri_ce_whatwg_invalid_url_exception, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? reason : "", reason ? ")" : ""); zend_update_property(exception->ce, exception, ZEND_STRL("errors"), &err); } if (errors != NULL) { diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 6b0139e186b62..bdbd2f52f0f2d 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -741,7 +741,7 @@ static ZEND_FUNCTION(zend_test_uri_parser) RETURN_THROWS(); } - uri_internal_t *uri = php_uri_parse(parser, ZSTR_VAL(uri_string), ZSTR_LEN(uri_string), false); + php_uri_internal *uri = php_uri_parse(parser, ZSTR_VAL(uri_string), ZSTR_LEN(uri_string), false); if (uri == NULL) { RETURN_THROWS(); } From f389aded6a24d32a5f65a2ddcd3fcb6bc3027284 Mon Sep 17 00:00:00 2001 From: Ilija Tovilo Date: Fri, 27 Jun 2025 20:36:47 +0200 Subject: [PATCH 2/5] Warn on http_response_code() after header('HTTP/...') Fixes GH-18582 Fixes #81451 Closes GH-18962 Co-authored-by: Jakub Zelenka --- NEWS | 4 ++++ ext/standard/head.c | 8 ++++++++ sapi/cli/tests/gh18582.phpt | 40 +++++++++++++++++++++++++++++++++++++ 3 files changed, 52 insertions(+) create mode 100644 sapi/cli/tests/gh18582.phpt diff --git a/NEWS b/NEWS index ece950165ad30..fbf733889a8bd 100644 --- a/NEWS +++ b/NEWS @@ -56,6 +56,10 @@ PHP NEWS - Reflection: . ReflectionConstant is no longer final. (sasezaki) +- SAPI: + . Fixed bug GH-18582 and #81451: http_response_code() does not override the + status code generated by header(). (ilutov, Jakub Zelenka) + - Standard: . Passing strings which are not one byte long to ord() is now deprecated. (Girgias) diff --git a/ext/standard/head.c b/ext/standard/head.c index f94c7f596c2c5..087ba6a34806c 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -381,6 +381,14 @@ PHP_FUNCTION(http_response_code) } RETURN_FALSE; } + + if (SG(sapi_headers).http_status_line) { + php_error_docref(NULL, E_WARNING, "Calling http_response_code() after header('HTTP/...') has no effect"); + // If it is decided that this should have effect in the future, replace warning with + // efree(SG(sapi_headers).http_status_line); + // SG(sapi_headers).http_status_line = NULL; + } + zend_long old_response_code; old_response_code = SG(sapi_headers).http_response_code; diff --git a/sapi/cli/tests/gh18582.phpt b/sapi/cli/tests/gh18582.phpt new file mode 100644 index 0000000000000..0c3cebf71c3d1 --- /dev/null +++ b/sapi/cli/tests/gh18582.phpt @@ -0,0 +1,40 @@ +--TEST-- +GH-18582: Allow http_response_code() to clear HTTP start-line +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 404 Not Found +Host: %s +Date: %s +Connection: close +X-Powered-By: %s +Content-type: text/html; charset=UTF-8 + +
+Warning: http_response_code(): Calling http_response_code() after header('HTTP/...') has no effect in %s on line 3
+404 +403 From d27e1e1723c4b4884cb5cc9288f38e4a57c2cef5 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 22 Sep 2025 03:02:01 +0100 Subject: [PATCH 3/5] core: Add new test for coercions from NAN --- Zend/tests/type_coercion/nan_comp_op.phpt | 106 +++++++++++++++++++++ Zend/tests/type_coercion/nan_to_other.phpt | 71 ++++++++++++++ ext/opcache/tests/jit/nan_bool_cast.phpt | 15 +++ 3 files changed, 192 insertions(+) create mode 100644 Zend/tests/type_coercion/nan_comp_op.phpt create mode 100644 Zend/tests/type_coercion/nan_to_other.phpt create mode 100644 ext/opcache/tests/jit/nan_bool_cast.phpt diff --git a/Zend/tests/type_coercion/nan_comp_op.phpt b/Zend/tests/type_coercion/nan_comp_op.phpt new file mode 100644 index 0000000000000..0be33cbb26ab6 --- /dev/null +++ b/Zend/tests/type_coercion/nan_comp_op.phpt @@ -0,0 +1,106 @@ +--TEST-- +NAN coerced to other types +--FILE-- + $right); + var_dump($nan >= $right); + var_dump($nan <=> $right); +} + +?> +--EXPECT-- +float(NAN) +Using 0 as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) +Using NULL as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +int(1) +Using false as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) +int(1) +Using true as right op +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +int(0) +Using '' as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) +Using array ( +) as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) +int(-1) +Using NAN as right op +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +int(1) diff --git a/Zend/tests/type_coercion/nan_to_other.phpt b/Zend/tests/type_coercion/nan_to_other.phpt new file mode 100644 index 0000000000000..e925d093791bb --- /dev/null +++ b/Zend/tests/type_coercion/nan_to_other.phpt @@ -0,0 +1,71 @@ +--TEST-- +NAN coerced to other types +--FILE-- + +--EXPECTF-- +float(NAN) +bool(true) +string(3) "NAN" + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) +bool(true) +string(3) "NAN" +array(1) { + [0]=> + float(NAN) +} +object(stdClass)#%d (1) { + ["scalar"]=> + float(NAN) +} +NULL +bool(true) + +Warning: The float NAN is not representable as an int, cast occurred in %s on line %d +int(0) +string(3) "NAN" +array(1) { + [0]=> + float(NAN) +} +object(stdClass)#%d (1) { + ["scalar"]=> + float(NAN) +} diff --git a/ext/opcache/tests/jit/nan_bool_cast.phpt b/ext/opcache/tests/jit/nan_bool_cast.phpt new file mode 100644 index 0000000000000..0a68a682412f1 --- /dev/null +++ b/ext/opcache/tests/jit/nan_bool_cast.phpt @@ -0,0 +1,15 @@ +--TEST-- +Const NAN with bool cast should emit 1 warning +--INI-- +opcache.enable=1 +opcache.enable_cli=1 +opcache.file_update_protection=0 +--EXTENSIONS-- +opcache +--FILE-- + +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line 2 +1 From 320fe2975bfd084c0e6528c3f617043a19bb1d24 Mon Sep 17 00:00:00 2001 From: Gina Peter Banyard Date: Mon, 22 Sep 2025 03:03:42 +0100 Subject: [PATCH 4/5] core: Warn when coercing NAN to other types RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types Closes GH-19573 --- NEWS | 1 + UPGRADING | 2 + Zend/Optimizer/block_pass.c | 24 ++++-- Zend/Optimizer/sccp.c | 4 + Zend/Optimizer/zend_inference.c | 6 +- Zend/Optimizer/zend_optimizer.c | 3 + Zend/tests/optimizer/nan_warning_switch.phpt | 17 +++++ .../explicit_casts_should_not_warn.phpt | 1 + .../explicit_casts_should_not_warn_32bit.phpt | 3 +- .../union_int_string_type_arg.phpt | 2 + Zend/tests/type_coercion/nan_to_other.phpt | 22 ++++++ .../settype_array_nan_with_error_handler.phpt | 24 ++++++ ...settype_array_nan_with_error_handler2.phpt | 24 ++++++ ...settype_array_nan_with_error_handler3.phpt | 24 ++++++ .../settype_bool_nan_with_error_handler.phpt | 21 ++++++ .../settype_bool_nan_with_error_handler2.phpt | 21 ++++++ .../settype_bool_nan_with_error_handler3.phpt | 21 ++++++ .../settype_int_nan_with_error_handler.phpt | 21 ++++++ .../settype_int_nan_with_error_handler2.phpt | 21 ++++++ .../settype_int_nan_with_error_handler3.phpt | 21 ++++++ .../settype_null_nan_with_error_handler.phpt | 21 ++++++ .../settype_null_nan_with_error_handler2.phpt | 21 ++++++ .../settype_null_nan_with_error_handler3.phpt | 21 ++++++ ...settype_object_nan_with_error_handler.phpt | 24 ++++++ ...ettype_object_nan_with_error_handler2.phpt | 24 ++++++ ...ettype_object_nan_with_error_handler3.phpt | 24 ++++++ ...settype_string_nan_with_error_handler.phpt | 21 ++++++ ...ettype_string_nan_with_error_handler2.phpt | 21 ++++++ ...ettype_string_nan_with_error_handler3.phpt | 21 ++++++ .../tests/type_declarations/scalar_basic.phpt | 2 + .../scalar_return_basic.phpt | 2 + .../scalar_return_basic_64bit.phpt | 2 + Zend/zend_compile.c | 33 +++------ Zend/zend_execute.h | 6 ++ Zend/zend_operators.c | 74 ++++++++++++++++--- Zend/zend_operators.h | 4 + ext/opcache/jit/zend_jit_helpers.c | 6 ++ ext/opcache/jit/zend_jit_ir.c | 15 +++- ext/opcache/tests/jit/nan_001.phpt | 7 +- ext/opcache/tests/jit/nan_002.phpt | 13 +++- .../range/range_inputs_float_NAN_values.phpt | 9 ++- .../get_defined_constants_basic.phpt | 2 +- ext/standard/tests/math/fpow.phpt | 17 +++-- ext/standard/tests/math/pow_basic.phpt | 67 ++++++++++------- ext/standard/tests/math/pow_basic_64bit.phpt | 67 ++++++++++------- 45 files changed, 697 insertions(+), 110 deletions(-) create mode 100644 Zend/tests/optimizer/nan_warning_switch.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt create mode 100644 Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt diff --git a/NEWS b/NEWS index fbf733889a8bd..b3ec552a8773f 100644 --- a/NEWS +++ b/NEWS @@ -17,6 +17,7 @@ PHP NEWS (nielsdos) . Casting floats that are not representable as ints now emits a warning. (Girgias) + . Casting NAN to other types now emits a warning. (Girgias) - Bz2: . Fixed bug GH-19810 (Broken bzopen() stream mode validation). (ilutov) diff --git a/UPGRADING b/UPGRADING index 92288ec984514..80c286cae5a19 100644 --- a/UPGRADING +++ b/UPGRADING @@ -59,6 +59,8 @@ PHP 8.5 UPGRADE NOTES floats) to int if they cannot be represented as one. This affects explicit int casts and implicit int casts. RFC: https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int + . A warning is now emitted when casting NAN to other types. + RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types - BZ2: . bzcompress() now throws a ValueError when $block_size is not between diff --git a/Zend/Optimizer/block_pass.c b/Zend/Optimizer/block_pass.c index 275c519d431be..77beec2f72a73 100644 --- a/Zend/Optimizer/block_pass.c +++ b/Zend/Optimizer/block_pass.c @@ -436,18 +436,11 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array Tsource[VAR_NUM(opline->op1.var)] = NULL; break; } - ZEND_FALLTHROUGH; - - case ZEND_IS_EQUAL: - case ZEND_IS_NOT_EQUAL: if (opline->op1_type == IS_CONST && opline->op2_type == IS_CONST) { goto optimize_constant_binary_op; } - /* IS_EQ(TRUE, X) => BOOL(X) - * IS_EQ(FALSE, X) => BOOL_NOT(X) - * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X) - * IS_NOT_EQ(FALSE, X) => BOOL(X) + /* * CASE(TRUE, X) => BOOL(X) * CASE(FALSE, X) => BOOL_NOT(X) */ @@ -478,6 +471,21 @@ static void zend_optimize_block(zend_basic_block *block, zend_op_array *op_array goto optimize_bool; } break; + + case ZEND_IS_EQUAL: + case ZEND_IS_NOT_EQUAL: + if (opline->op1_type == IS_CONST && + opline->op2_type == IS_CONST) { + goto optimize_constant_binary_op; + } + /* IS_EQ(TRUE, X) => BOOL(X) + * IS_EQ(FALSE, X) => BOOL_NOT(X) + * IS_NOT_EQ(TRUE, X) => BOOL_NOT(X) + * IS_NOT_EQ(FALSE, X) => BOOL(X) + * Those optimizations are not safe if the other operand ends up being NAN + * as BOOL/BOOL_NOT will warn, while IS_EQUAL/IS_NOT_EQUAL do not. + */ + break; case ZEND_IS_IDENTICAL: if (opline->op1_type == IS_CONST && opline->op2_type == IS_CONST) { diff --git a/Zend/Optimizer/sccp.c b/Zend/Optimizer/sccp.c index 9b8216e589bea..5bae5cf160324 100644 --- a/Zend/Optimizer/sccp.c +++ b/Zend/Optimizer/sccp.c @@ -335,6 +335,10 @@ static inline zend_result ct_eval_bool_cast(zval *result, zval *op) { ZVAL_TRUE(result); return SUCCESS; } + /* NAN warns when casting */ + if (Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op))) { + return FAILURE; + } ZVAL_BOOL(result, zend_is_true(op)); return SUCCESS; diff --git a/Zend/Optimizer/zend_inference.c b/Zend/Optimizer/zend_inference.c index 7f84ed55de60e..435edeef18c36 100644 --- a/Zend/Optimizer/zend_inference.c +++ b/Zend/Optimizer/zend_inference.c @@ -5109,14 +5109,16 @@ ZEND_API bool zend_may_throw_ex(const zend_op *opline, const zend_ssa_op *ssa_op case ZEND_PRE_DEC: case ZEND_POST_DEC: return (t1 & (MAY_BE_NULL|MAY_BE_FALSE|MAY_BE_TRUE|MAY_BE_STRING|MAY_BE_ARRAY|MAY_BE_OBJECT|MAY_BE_RESOURCE)); - case ZEND_BOOL_NOT: case ZEND_JMPZ: case ZEND_JMPNZ: case ZEND_JMPZ_EX: case ZEND_JMPNZ_EX: - case ZEND_BOOL: case ZEND_JMP_SET: return (t1 & MAY_BE_OBJECT); + case ZEND_BOOL: + case ZEND_BOOL_NOT: + /* NAN Cast to bool will warn, but if we have a range it is fine */ + return (t1 & MAY_BE_OBJECT) || ((t1 & MAY_BE_DOUBLE) && !OP1_HAS_RANGE()); case ZEND_BOOL_XOR: return (t1 & MAY_BE_OBJECT) || (t2 & MAY_BE_OBJECT); case ZEND_IS_EQUAL: diff --git a/Zend/Optimizer/zend_optimizer.c b/Zend/Optimizer/zend_optimizer.c index 1c58d6b7372fb..80eabe97c3217 100644 --- a/Zend/Optimizer/zend_optimizer.c +++ b/Zend/Optimizer/zend_optimizer.c @@ -74,6 +74,9 @@ zend_result zend_optimizer_eval_unary_op(zval *result, uint8_t opcode, zval *op1 } return unary_op(result, op1); } else { /* ZEND_BOOL */ + if (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) { + return FAILURE; + } ZVAL_BOOL(result, zend_is_true(op1)); return SUCCESS; } diff --git a/Zend/tests/optimizer/nan_warning_switch.phpt b/Zend/tests/optimizer/nan_warning_switch.phpt new file mode 100644 index 0000000000000..1b7b404201f44 --- /dev/null +++ b/Zend/tests/optimizer/nan_warning_switch.phpt @@ -0,0 +1,17 @@ +--TEST-- +Checking NAN in a switch statement with true/false +--FILE-- + +--EXPECT-- +true diff --git a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt index 2b876597b9b1e..4ef1215461885 100644 --- a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt +++ b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn.phpt @@ -26,6 +26,7 @@ foreach($values as $value) { ?> --EXPECTF-- +Warning: unexpected NAN value was coerced to string in %s on line %d int(3) int(3) diff --git a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt index b34e762dfff35..3165d653d0478 100644 --- a/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt +++ b/Zend/tests/type_coercion/float_to_int/explicit_casts_should_not_warn_32bit.phpt @@ -1,5 +1,5 @@ --TEST-- -Explicit (int) cast must not warn 32bit variation +Explicit (int) cast must not warn if value is representable 32bit variation --SKIPIF-- --EXPECTF-- +Warning: unexpected NAN value was coerced to string in %s on line %d int(3) int(3) diff --git a/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt b/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt index 3208b44e1ad29..9b1f057b7484f 100644 --- a/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt +++ b/Zend/tests/type_coercion/float_to_int/union_int_string_type_arg.phpt @@ -23,6 +23,8 @@ int(1) Deprecated: Implicit conversion from float 1.5 to int loses precision in %s on line %d int(1) + +Warning: unexpected NAN value was coerced to string in %s on line %d string(3) "NAN" string(8) "1.0E+121" string(3) "INF" diff --git a/Zend/tests/type_coercion/nan_to_other.phpt b/Zend/tests/type_coercion/nan_to_other.phpt index e925d093791bb..2918d1a8ccf4f 100644 --- a/Zend/tests/type_coercion/nan_to_other.phpt +++ b/Zend/tests/type_coercion/nan_to_other.phpt @@ -40,31 +40,53 @@ foreach ($types as $type) { ?> --EXPECTF-- float(NAN) + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) + +Warning: unexpected NAN value was coerced to string in %s on line %d string(3) "NAN" Warning: The float NAN is not representable as an int, cast occurred in %s on line %d int(0) + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) + +Warning: unexpected NAN value was coerced to string in %s on line %d string(3) "NAN" + +Warning: unexpected NAN value was coerced to array in %s on line %d array(1) { [0]=> float(NAN) } + +Warning: unexpected NAN value was coerced to object in %s on line %d object(stdClass)#%d (1) { ["scalar"]=> float(NAN) } + +Warning: unexpected NAN value was coerced to null in %s on line %d NULL + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) Warning: The float NAN is not representable as an int, cast occurred in %s on line %d int(0) + +Warning: unexpected NAN value was coerced to string in %s on line %d string(3) "NAN" + +Warning: unexpected NAN value was coerced to array in %s on line %d array(1) { [0]=> float(NAN) } + +Warning: unexpected NAN value was coerced to object in %s on line %d object(stdClass)#%d (1) { ["scalar"]=> float(NAN) diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..b07d975d7b2fa --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + NULL +} diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..681b015593026 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + float(NAN) +} diff --git a/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..1dae45a6ebec5 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_array_nan_with_error_handler3.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to array 3 +--FILE-- + +--EXPECTF-- +float(NAN) +unexpected NAN value was coerced to array +array(1) { + [0]=> + string(8) "%s" +} diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..5f854c54ddbdd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..1377228a9da64 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..ceb17da96408f --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_bool_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to bool 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to bool +bool(true) diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..4f00f51331e0d --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..65c048158f8a5 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int 2 +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..4e715bdcca1bd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_int_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to int 3 +--FILE-- + +--EXPECT-- +float(NAN) +The float NAN is not representable as an int, cast occurred +int(0) diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..d89cb55443241 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..41c095ff3f0b2 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..9a289b4151aa2 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_null_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to null 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to null +NULL diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..19e36fa3d4fcd --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + NULL +} diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..b605d0ff9e7e5 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + float(NAN) +} diff --git a/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..b3789f2a9c572 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_object_nan_with_error_handler3.phpt @@ -0,0 +1,24 @@ +--TEST-- +Error handler dtor NAN value, set to object 3 +--FILE-- + +--EXPECTF-- +float(NAN) +unexpected NAN value was coerced to object +object(stdClass)#2 (1) { + ["scalar"]=> + string(8) "%s" +} diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt new file mode 100644 index 0000000000000..d3a52996f4ddb --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt new file mode 100644 index 0000000000000..17921e5ae5308 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string 2 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" \ No newline at end of file diff --git a/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt new file mode 100644 index 0000000000000..0a8718780abd2 --- /dev/null +++ b/Zend/tests/type_coercion/settype/settype_string_nan_with_error_handler3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Error handler dtor NAN value, set to string 3 +--FILE-- + +--EXPECT-- +float(NAN) +unexpected NAN value was coerced to string +string(3) "NAN" diff --git a/Zend/tests/type_declarations/scalar_basic.phpt b/Zend/tests/type_declarations/scalar_basic.phpt index 6b2cf736edbf9..352c48f8a9e07 100644 --- a/Zend/tests/type_declarations/scalar_basic.phpt +++ b/Zend/tests/type_declarations/scalar_basic.phpt @@ -194,6 +194,7 @@ string(0) "" string(%d) "%d" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) @@ -247,6 +248,7 @@ bool(false) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) diff --git a/Zend/tests/type_declarations/scalar_return_basic.phpt b/Zend/tests/type_declarations/scalar_return_basic.phpt index 8f827600328ed..67af304ec2c69 100644 --- a/Zend/tests/type_declarations/scalar_return_basic.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic.phpt @@ -156,6 +156,7 @@ string(0) "" *** Trying int(2147483647) string(10) "2147483647" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) string(1) "1" @@ -193,6 +194,7 @@ bool(false) *** Trying int(2147483647) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) bool(true) diff --git a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt index 0a32dd3f16f23..498092e8ac543 100644 --- a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt @@ -156,6 +156,7 @@ string(0) "" *** Trying int(9223372036854775807) string(19) "9223372036854775807" *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to string on line %d string(3) "NAN" *** Trying bool(true) string(1) "1" @@ -193,6 +194,7 @@ bool(false) *** Trying int(9223372036854775807) bool(true) *** Trying float(NAN) +E_WARNING: unexpected NAN value was coerced to bool on line %d bool(true) *** Trying bool(true) bool(true) diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index b46b5d5bff8d2..ce4b4e3b7fd52 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -10046,6 +10046,11 @@ ZEND_API bool zend_unary_op_produces_error(uint32_t opcode, const zval *op) } return Z_TYPE_P(op) <= IS_TRUE || !zend_is_op_long_compatible(op); } + /* Can happen when called from zend_optimizer_eval_unary_op() */ + if (opcode == ZEND_BOOL || opcode == ZEND_BOOL_NOT) { + /* ZEND_BOOL/ZEND_BOOL_NOT warns when casting NAN. */ + return Z_TYPE_P(op) == IS_DOUBLE; + } return 0; } @@ -10229,29 +10234,7 @@ static void zend_compile_binary_op(znode *result, zend_ast *ast) /* {{{ */ } do { - if (opcode == ZEND_IS_EQUAL || opcode == ZEND_IS_NOT_EQUAL) { - if (left_node.op_type == IS_CONST) { - if (Z_TYPE(left_node.u.constant) == IS_FALSE) { - opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &right_node, NULL); - break; - } else if (Z_TYPE(left_node.u.constant) == IS_TRUE) { - opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &right_node, NULL); - break; - } - } else if (right_node.op_type == IS_CONST) { - if (Z_TYPE(right_node.u.constant) == IS_FALSE) { - opcode = (opcode == ZEND_IS_NOT_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &left_node, NULL); - break; - } else if (Z_TYPE(right_node.u.constant) == IS_TRUE) { - opcode = (opcode == ZEND_IS_EQUAL) ? ZEND_BOOL : ZEND_BOOL_NOT; - zend_emit_op_tmp(result, opcode, &left_node, NULL); - break; - } - } - } else if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) { + if (opcode == ZEND_IS_IDENTICAL || opcode == ZEND_IS_NOT_IDENTICAL) { /* convert $x === null to is_null($x) (i.e. ZEND_TYPE_CHECK opcode). Do the same thing for false/true. (covers IS_NULL, IS_FALSE, and IS_TRUE) */ if (left_node.op_type == IS_CONST) { if (Z_TYPE(left_node.u.constant) <= IS_TRUE && Z_TYPE(left_node.u.constant) >= IS_NULL) { @@ -12058,6 +12041,10 @@ static zend_op *zend_delayed_compile_var(znode *result, zend_ast *ast, uint32_t bool zend_try_ct_eval_cast(zval *result, uint32_t type, zval *op1) { + /* NAN warns when casting */ + if (UNEXPECTED(Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1)))) { + return false; + } switch (type) { case _IS_BOOL: ZVAL_BOOL(result, zval_is_true(op1)); diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 13fb1ab7667a3..c08adf2a41b90 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -234,6 +234,9 @@ static zend_always_inline void zend_cast_zval_to_object(zval *result, zval *expr } Z_OBJ_P(result)->properties = ht; } else if (Z_TYPE_P(expr) != IS_NULL) { + if (UNEXPECTED(Z_TYPE_P(expr) == IS_DOUBLE && zend_isnan(Z_DVAL_P(expr)))) { + zend_nan_coerced_to_type_warning(IS_OBJECT); + } Z_OBJ_P(result)->properties = ht = zend_new_array(1); expr = zend_hash_add_new(ht, ZSTR_KNOWN(ZEND_STR_SCALAR), expr); if (op1_type == IS_CONST) { @@ -248,6 +251,9 @@ static zend_always_inline void zend_cast_zval_to_array(zval *result, zval *expr, extern zend_class_entry *zend_ce_closure; if (op1_type == IS_CONST || Z_TYPE_P(expr) != IS_OBJECT || Z_OBJCE_P(expr) == zend_ce_closure) { if (Z_TYPE_P(expr) != IS_NULL) { + if (UNEXPECTED(Z_TYPE_P(expr) == IS_DOUBLE && zend_isnan(Z_DVAL_P(expr)))) { + zend_nan_coerced_to_type_warning(IS_ARRAY); + } ZVAL_ARR(result, zend_new_array(1)); expr = zend_hash_index_add_new(Z_ARRVAL_P(result), 0, expr); if (op1_type == IS_CONST) { diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 91421b45fdf31..36df6915db6a7 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -574,9 +574,13 @@ ZEND_API void ZEND_FASTCALL convert_to_long(zval *op) /* {{{ */ break; case IS_LONG: break; - case IS_DOUBLE: - ZVAL_LONG(op, zend_dval_to_lval(Z_DVAL_P(op))); + case IS_DOUBLE: { + /* NAN might emit a warning */ + zend_long new_value = zend_dval_to_lval(Z_DVAL_P(op)); + zval_ptr_dtor(op); + ZVAL_LONG(op, new_value); break; + } case IS_STRING: { zend_string *str = Z_STR_P(op); @@ -672,6 +676,9 @@ ZEND_API void ZEND_FASTCALL convert_to_double(zval *op) /* {{{ */ ZEND_API void ZEND_FASTCALL convert_to_null(zval *op) /* {{{ */ { + if (UNEXPECTED(Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op)))) { + zend_nan_coerced_to_type_warning(IS_NULL); + } zval_ptr_dtor(op); ZVAL_NULL(op); } @@ -699,9 +706,16 @@ ZEND_API void ZEND_FASTCALL convert_to_boolean(zval *op) /* {{{ */ case IS_LONG: ZVAL_BOOL(op, Z_LVAL_P(op) ? 1 : 0); break; - case IS_DOUBLE: - ZVAL_BOOL(op, Z_DVAL_P(op) ? 1 : 0); + case IS_DOUBLE: { + /* We compute the new value before emitting the warning as the zval may change */ + bool new_value = Z_DVAL_P(op) ? true : false; + if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) { + zend_nan_coerced_to_type_warning(_IS_BOOL); + zval_ptr_dtor(op); + } + ZVAL_BOOL(op, new_value); break; + } case IS_STRING: { zend_string *str = Z_STR_P(op); @@ -766,9 +780,13 @@ ZEND_API void ZEND_FASTCALL _convert_to_string(zval *op) /* {{{ */ case IS_LONG: ZVAL_STR(op, zend_long_to_str(Z_LVAL_P(op))); break; - case IS_DOUBLE: - ZVAL_NEW_STR(op, zend_double_to_str(Z_DVAL_P(op))); + case IS_DOUBLE: { + /* Casting NAN will cause a warning */ + zend_string *new_value = zend_double_to_str(Z_DVAL_P(op)); + zval_ptr_dtor(op); + ZVAL_NEW_STR(op, new_value); break; + } case IS_ARRAY: zend_error(E_WARNING, "Array to string conversion"); zval_ptr_dtor(op); @@ -813,6 +831,9 @@ ZEND_API bool ZEND_FASTCALL _try_convert_to_string(zval *op) /* {{{ */ static void convert_scalar_to_array(zval *op) /* {{{ */ { + if (UNEXPECTED(Z_TYPE_P(op) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op)))) { + zend_nan_coerced_to_type_warning(IS_ARRAY); + } HashTable *ht = zend_new_array(1); zend_hash_index_add_new(ht, 0, op); ZVAL_ARR(op, ht); @@ -895,6 +916,11 @@ ZEND_API void ZEND_FASTCALL convert_to_object(zval *op) /* {{{ */ case IS_REFERENCE: zend_unwrap_reference(op); goto try_again; + case IS_DOUBLE: + if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) { + zend_nan_coerced_to_type_warning(IS_OBJECT); + } + ZEND_FALLTHROUGH; default: { zval tmp; ZVAL_COPY_VALUE(&tmp, op); @@ -923,6 +949,11 @@ ZEND_API void ZEND_COLD zend_oob_string_to_long_error(const zend_string *s) zend_error_unchecked(E_WARNING, "The float-string \"%s\" is not representable as an int, cast occurred", ZSTR_VAL(s)); } +ZEND_API void ZEND_COLD zend_nan_coerced_to_type_warning(uint8_t type) +{ + zend_error(E_WARNING, "unexpected NAN value was coerced to %s", zend_get_type_by_const(type)); +} + ZEND_API zend_long ZEND_FASTCALL zval_get_long_func(const zval *op, bool is_strict) /* {{{ */ { try_again: @@ -2254,6 +2285,8 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */ double str_dval; uint8_t type = is_numeric_string(ZSTR_VAL(str), ZSTR_LEN(str), &str_lval, &str_dval, 0); + ZEND_ASSERT(!zend_isnan(dval)); + if (type == IS_LONG) { return ZEND_THREEWAY_COMPARE(dval, (double) str_lval); } @@ -2272,7 +2305,7 @@ static int compare_double_to_string(double dval, zend_string *str) /* {{{ */ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */ { - int converted = 0; + bool converted = false; zval op1_copy, op2_copy; while (1) { @@ -2379,7 +2412,27 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */ } if (!converted) { - if (Z_TYPE_P(op1) < IS_TRUE) { + /* Handle NAN */ + if (UNEXPECTED( + (Z_TYPE_P(op1) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op1))) + || (Z_TYPE_P(op2) == IS_DOUBLE && zend_isnan(Z_DVAL_P(op2))) + )) { + // TODO: NAN should always be uncomparable + /* NAN used be cast to TRUE so handle this manually for the time being */ + if (Z_TYPE_P(op1) < IS_TRUE) { + return -1; + } else if (Z_TYPE_P(op1) == IS_TRUE || Z_TYPE_P(op2) == IS_TRUE) { + return 0; + } else if (Z_TYPE_P(op2) < IS_TRUE) { + return 1; + } else if (Z_TYPE_P(op1) != IS_DOUBLE) { + op1 = _zendi_convert_scalar_to_number_silent(op1, &op1_copy); + converted = true; + } else if (Z_TYPE_P(op2) != IS_DOUBLE) { + op2 = _zendi_convert_scalar_to_number_silent(op2, &op2_copy); + converted = true; + } + } else if (Z_TYPE_P(op1) < IS_TRUE) { return zval_is_true(op2) ? -1 : 0; } else if (Z_TYPE_P(op1) == IS_TRUE) { return zval_is_true(op2) ? 0 : 1; @@ -2393,7 +2446,7 @@ ZEND_API int ZEND_FASTCALL zend_compare(zval *op1, zval *op2) /* {{{ */ if (EG(exception)) { return 1; /* to stop comparison of arrays */ } - converted = 1; + converted = true; } } else if (Z_TYPE_P(op1)==IS_ARRAY) { return 1; @@ -3551,6 +3604,9 @@ ZEND_API zend_string* ZEND_FASTCALL zend_double_to_str(double num) int precision = (int) EG(precision); zend_gcvt(num, precision ? precision : 1, '.', 'E', buf); zend_string *str = zend_string_init(buf, strlen(buf), 0); + if (UNEXPECTED(zend_isnan(num))) { + zend_nan_coerced_to_type_warning(IS_STRING); + } GC_ADD_FLAGS(str, IS_STR_VALID_UTF8); return str; } diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index e821827f57f58..a3bf19fca8f27 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -119,6 +119,7 @@ ZEND_API void zend_incompatible_double_to_long_error(double d); ZEND_API void zend_incompatible_string_to_long_error(const zend_string *s); ZEND_API void ZEND_COLD zend_oob_double_to_long_error(double d); ZEND_API void ZEND_COLD zend_oob_string_to_long_error(const zend_string *s); +ZEND_API void ZEND_COLD zend_nan_coerced_to_type_warning(uint8_t type); ZEND_API zend_long ZEND_FASTCALL zend_dval_to_lval_slow(double d); @@ -421,6 +422,9 @@ static zend_always_inline bool i_zend_is_true(const zval *op) } break; case IS_DOUBLE: + if (UNEXPECTED(zend_isnan(Z_DVAL_P(op)))) { + zend_nan_coerced_to_type_warning(_IS_BOOL); + } if (Z_DVAL_P(op)) { result = 1; } diff --git a/ext/opcache/jit/zend_jit_helpers.c b/ext/opcache/jit/zend_jit_helpers.c index 8e13daf99bc34..787eb4d07a8b6 100644 --- a/ext/opcache/jit/zend_jit_helpers.c +++ b/ext/opcache/jit/zend_jit_helpers.c @@ -16,6 +16,7 @@ +----------------------------------------------------------------------+ */ +#include "Zend/zend_portability.h" #include "Zend/zend_types.h" #include "Zend/zend_API.h" @@ -2653,6 +2654,11 @@ static void ZEND_FASTCALL zend_jit_invalid_array_access(zval *container) zend_error(E_WARNING, "Trying to access array offset on %s", zend_zval_value_name(container)); } +static void ZEND_FASTCALL zend_jit_nan_coerced_to_type_warning(void) +{ + zend_nan_coerced_to_type_warning(_IS_BOOL); +} + static void ZEND_FASTCALL zend_jit_invalid_property_read(zval *container, const char *property_name) { zend_error(E_WARNING, "Attempt to read property \"%s\" on %s", property_name, zend_zval_value_name(container)); diff --git a/ext/opcache/jit/zend_jit_ir.c b/ext/opcache/jit/zend_jit_ir.c index e0f8677f32889..112d09fe165e2 100644 --- a/ext/opcache/jit/zend_jit_ir.c +++ b/ext/opcache/jit/zend_jit_ir.c @@ -16,6 +16,7 @@ * +----------------------------------------------------------------------+ */ +#include "Zend/zend_types.h" #include "Zend/zend_type_info.h" #include "jit/ir/ir.h" #include "jit/ir/ir_builder.h" @@ -7566,7 +7567,9 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 op1_addr = ZEND_ADDR_REF_ZVAL(ref); } - if (Z_MODE(op1_addr) == IS_CONST_ZVAL) { + if (Z_MODE(op1_addr) == IS_CONST_ZVAL + /* NAN Value must cause a warning to be emitted */ + && (Z_TYPE_P(Z_ZV(op1_addr)) != IS_DOUBLE || !zend_isnan(Z_DVAL_P(Z_ZV(op1_addr))))) { if (zend_is_true(Z_ZV(op1_addr))) { always_true = 1; } else { @@ -7734,7 +7737,15 @@ static int zend_jit_bool_jmpznz(zend_jit_ctx *jit, const zend_op *opline, uint32 if_double = ir_IF(ir_EQ(type, ir_CONST_U8(IS_DOUBLE))); ir_IF_TRUE(if_double); } - ref = ir_NE(jit_Z_DVAL(jit, op1_addr), ir_CONST_DOUBLE(0.0)); + + ir_ref dval = jit_Z_DVAL(jit, op1_addr); + ir_ref is_nan = ir_NE(dval, dval); + ir_ref if_val = ir_IF(is_nan); + ir_IF_TRUE_cold(if_val); + ir_CALL(IR_VOID, ir_CONST_FC_FUNC(zend_jit_nan_coerced_to_type_warning)); + ir_MERGE_WITH_EMPTY_FALSE(if_val); + + ref = ir_NE(dval, ir_CONST_DOUBLE(0.0)); if (branch_opcode == ZEND_BOOL || branch_opcode == ZEND_BOOL_NOT) { if (set_bool_not) { jit_set_Z_TYPE_INFO_ref(jit, jit_ZVAL_ADDR(jit, res_addr), diff --git a/ext/opcache/tests/jit/nan_001.phpt b/ext/opcache/tests/jit/nan_001.phpt index 3ff102745414f..c243d7883cf0f 100644 --- a/ext/opcache/tests/jit/nan_001.phpt +++ b/ext/opcache/tests/jit/nan_001.phpt @@ -13,7 +13,12 @@ for ($i = 0; $i < 3; $i++) { else { echo "nan is false\n"; } } ?> ---EXPECT-- +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line %d nan is true + +Warning: unexpected NAN value was coerced to bool in %s on line %d nan is true + +Warning: unexpected NAN value was coerced to bool in %s on line %d nan is true diff --git a/ext/opcache/tests/jit/nan_002.phpt b/ext/opcache/tests/jit/nan_002.phpt index 01cb1ebb40d40..e77d3c5edd036 100644 --- a/ext/opcache/tests/jit/nan_002.phpt +++ b/ext/opcache/tests/jit/nan_002.phpt @@ -33,9 +33,16 @@ test2(NAN, false); test2(1.0, false); test2(0.0, false); ?> ---EXPECT-- +--EXPECTF-- +Warning: unexpected NAN value was coerced to bool in %s on line %d string(1) "1" + +Warning: unexpected NAN value was coerced to bool in %s on line %d + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(false) string(1) "1" @@ -46,10 +53,14 @@ string(1) "2" bool(false) bool(true) + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) bool(true) bool(false) + +Warning: unexpected NAN value was coerced to bool in %s on line %d bool(true) bool(true) bool(false) diff --git a/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt b/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt index 03ed069fd893a..cbfd2e9144131 100644 --- a/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt +++ b/ext/standard/tests/array/range/range_inputs_float_NAN_values.phpt @@ -16,9 +16,16 @@ var_dump($f3); $fs = [$f1, $f2, $f3, 5.5]; +function safe_to_string(int|float $number): string { + if (is_nan($number)) { + return 'NAN'; + } + return $number; +} + foreach ($fs as $s) { foreach ($fs as $e) { - echo "range($s, $e);\n"; + echo 'range(', safe_to_string($s), ', ', safe_to_string($e), ");\n"; try { var_dump( range($s, $e) ); } catch (\ValueError $e) { diff --git a/ext/standard/tests/general_functions/get_defined_constants_basic.phpt b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt index b89cc937aae8c..f701945fb0e7d 100644 --- a/ext/standard/tests/general_functions/get_defined_constants_basic.phpt +++ b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt @@ -9,7 +9,7 @@ var_dump(gettype(get_defined_constants())); $arr1 = get_defined_constants(false); $arr2 = get_defined_constants(); -var_dump(array_diff($arr1, $arr2)); +var_dump(array_diff_key($arr1, $arr2)); $n1 = count(get_defined_constants()); define("USER_CONSTANT", "test"); diff --git a/ext/standard/tests/math/fpow.phpt b/ext/standard/tests/math/fpow.phpt index 3f3c64862e81e..524051ba26c48 100644 --- a/ext/standard/tests/math/fpow.phpt +++ b/ext/standard/tests/math/fpow.phpt @@ -24,13 +24,20 @@ $numbers = [ NAN, ]; +function safe_to_string(int|float $number): string { + if (is_nan($number)) { + return 'NAN'; + } + return $number; +} + foreach ($numbers as $base) { foreach ($numbers as $exp) { - print str_pad($base, 4, " ", STR_PAD_LEFT) . - " ** " . - str_pad($exp, 4) . - " = " . - fpow($base, $exp) . + echo str_pad(safe_to_string($base), 4, " ", STR_PAD_LEFT), + " ** ", + str_pad(safe_to_string($exp), 4), + " = ", + safe_to_string(fpow($base, $exp)), PHP_EOL; } } diff --git a/ext/standard/tests/math/pow_basic.phpt b/ext/standard/tests/math/pow_basic.phpt index bc594b27c631a..847e569a47996 100644 --- a/ext/standard/tests/math/pow_basic.phpt +++ b/ext/standard/tests/math/pow_basic.phpt @@ -8,40 +8,51 @@ if (PHP_INT_SIZE != 4) die("skip this test is for 32bit platform only"); ?> --FILE-- --FILE-- Date: Tue, 23 Sep 2025 11:32:12 +0200 Subject: [PATCH 5/5] Fix build when --with-openssl-legacy-provider set It was missing proper backend init split. Closes GH-19930 --- NEWS | 3 +++ ext/openssl/openssl.c | 5 ----- ext/openssl/openssl_backend_common.c | 17 +---------------- ext/openssl/openssl_backend_v1.c | 16 ++++++++++++++++ ext/openssl/openssl_backend_v3.c | 12 ++++++++++++ 5 files changed, 32 insertions(+), 21 deletions(-) diff --git a/NEWS b/NEWS index b3ec552a8773f..b8e04d9d018ba 100644 --- a/NEWS +++ b/NEWS @@ -51,6 +51,9 @@ PHP NEWS (Arnaud) . Fixed bug GH-19831 (function JIT may not deref property value). (Arnaud) +- OpenSSL: + . Fixed build when --with-openssl-legacy-provider set. (Jakub Zelenka) + - MBstring: . Updated Unicode data tables to Unicode 17.0. (Yuya Hamada) diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c index 65ae0372253c0..cb134e9154b52 100644 --- a/ext/openssl/openssl.c +++ b/ext/openssl/openssl.c @@ -53,11 +53,6 @@ #include #include #include -#if PHP_OPENSSL_API_VERSION >= 0x30000 -#include -#include -#include -#endif ZEND_DECLARE_MODULE_GLOBALS(openssl) diff --git a/ext/openssl/openssl_backend_common.c b/ext/openssl/openssl_backend_common.c index 5a8919d3eacf2..ea52531bde45b 100644 --- a/ext/openssl/openssl_backend_common.c +++ b/ext/openssl/openssl_backend_common.c @@ -473,23 +473,8 @@ zend_result php_openssl_write_rand_file(const char * file, int egdsocket, int se return SUCCESS; } -void php_openssl_backend_init(void) +void php_openssl_backend_init_common(void) { -#ifdef LIBRESSL_VERSION_NUMBER - OPENSSL_config(NULL); - SSL_library_init(); - OpenSSL_add_all_ciphers(); - OpenSSL_add_all_digests(); - OpenSSL_add_all_algorithms(); - SSL_load_error_strings(); -#else -#if PHP_OPENSSL_API_VERSION >= 0x30000 && defined(LOAD_OPENSSL_LEGACY_PROVIDER) - OSSL_PROVIDER_load(NULL, "legacy"); - OSSL_PROVIDER_load(NULL, "default"); -#endif - OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); -#endif - /* Determine default SSL configuration file */ char *config_filename = getenv("OPENSSL_CONF"); if (config_filename == NULL) { diff --git a/ext/openssl/openssl_backend_v1.c b/ext/openssl/openssl_backend_v1.c index c15fff2f795ed..e95f51905f697 100644 --- a/ext/openssl/openssl_backend_v1.c +++ b/ext/openssl/openssl_backend_v1.c @@ -27,6 +27,22 @@ #include #endif +void php_openssl_backend_init(void) +{ +#ifdef LIBRESSL_VERSION_NUMBER + OPENSSL_config(NULL); + SSL_library_init(); + OpenSSL_add_all_ciphers(); + OpenSSL_add_all_digests(); + OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); +#else + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); +#endif + + php_openssl_backend_init_common(); +} + void php_openssl_backend_shutdown(void) { #ifdef LIBRESSL_VERSION_NUMBER diff --git a/ext/openssl/openssl_backend_v3.c b/ext/openssl/openssl_backend_v3.c index 16f145b2c5f5e..e037d9e13f587 100644 --- a/ext/openssl/openssl_backend_v3.c +++ b/ext/openssl/openssl_backend_v3.c @@ -24,6 +24,18 @@ ZEND_EXTERN_MODULE_GLOBALS(openssl) +void php_openssl_backend_init(void) +{ +#if PHP_OPENSSL_API_VERSION >= 0x30000 && defined(LOAD_OPENSSL_LEGACY_PROVIDER) + OSSL_PROVIDER_load(NULL, "legacy"); + OSSL_PROVIDER_load(NULL, "default"); +#endif + + OPENSSL_init_ssl(OPENSSL_INIT_LOAD_CONFIG, NULL); + + php_openssl_backend_init_common(); +} + void php_openssl_backend_shutdown(void) { (void) 0;