From f03a545376a5c4671e82a80a1889555418f7532d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 15 Sep 2025 21:54:17 +0200 Subject: [PATCH 1/5] uri: Add `UriError` --- ext/uri/php_uri.c | 2 ++ ext/uri/php_uri.stub.php | 5 +++++ ext/uri/php_uri_arginfo.h | 12 +++++++++++- ext/uri/php_uri_common.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index e5436d7f1e369..021f3727b8dd1 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -38,6 +38,7 @@ 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; @@ -1105,6 +1106,7 @@ static PHP_MINIT_FUNCTION(uri) 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(); diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index b4063bee8f596..9f12fbb1c0701 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -8,6 +8,11 @@ class UriException extends \Exception { } + /** @strict-properties */ + class UriError extends \Error + { + } + /** @strict-properties */ class InvalidUriException extends \Uri\UriException { diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 12a498357ea28..602e996b1a226 100644 --- a/ext/uri/php_uri_arginfo.h +++ b/ext/uri/php_uri_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: bf37e0babfcc453ab0c75d0e87e142dfa3b5e61e */ + * Stub hash: f3c524798d1933a400cc9377cfbfdcbaf77b87f0 */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_parse, 0, 1, IS_STATIC, 1) ZEND_ARG_TYPE_INFO(0, uri, IS_STRING, 0) @@ -321,6 +321,16 @@ static zend_class_entry *register_class_Uri_UriException(zend_class_entry *class return class_entry; } +static zend_class_entry *register_class_Uri_UriError(zend_class_entry *class_entry_Error) +{ + zend_class_entry ce, *class_entry; + + INIT_NS_CLASS_ENTRY(ce, "Uri", "UriError", NULL); + class_entry = zend_register_internal_class_with_flags(&ce, class_entry_Error, ZEND_ACC_NO_DYNAMIC_PROPERTIES); + + return class_entry; +} + static zend_class_entry *register_class_Uri_InvalidUriException(zend_class_entry *class_entry_Uri_UriException) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index f061db6f981b1..ba5b0b2d7ee46 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -23,6 +23,7 @@ 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; From 054a11f676f094903ccc75034e7fc2ea7835f292 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 15 Sep 2025 21:54:52 +0200 Subject: [PATCH 2/5] uri: Throw `UriError` for unexpected failures in uri_parser_rfc3986 This is a follow-up for php/php-src#19779 which updated the error *messages* for the non-syntax errors, but did not update the exception class, still implying it's related to invalid URIs. Given that we don't know ourselves if these are reachable in practice, they are cannot be meaningfully handled by a user of PHP. Thus this should be a `Error` according to our exception policy. --- ext/uri/uri_parser_rfc3986.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 583d3b9f5e0ae..c60c86efbfc36 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -136,7 +136,7 @@ static zend_result php_uri_parser_rfc3986_scheme_write(void *uri, zval *value, z return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the scheme", 0); + zend_throw_exception(uri_error_ce, "Failed to update the scheme", 0); return FAILURE; } } @@ -176,7 +176,7 @@ zend_result php_uri_parser_rfc3986_userinfo_write(void *uri, zval *value, zval * return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the userinfo", 0); + zend_throw_exception(uri_error_ce, "Failed to update the userinfo", 0); return FAILURE; } } @@ -271,7 +271,7 @@ static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the host", 0); + zend_throw_exception(uri_error_ce, "Failed to update the host", 0); return FAILURE; } } @@ -331,7 +331,7 @@ static zend_result php_uri_parser_rfc3986_port_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the port", 0); + zend_throw_exception(uri_error_ce, "Failed to update the port", 0); return FAILURE; } } @@ -383,7 +383,7 @@ static zend_result php_uri_parser_rfc3986_path_write(void *uri, zval *value, zva return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the path", 0); + zend_throw_exception(uri_error_ce, "Failed to update the path", 0); return FAILURE; } } @@ -420,7 +420,7 @@ static zend_result php_uri_parser_rfc3986_query_write(void *uri, zval *value, zv return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the query", 0); + zend_throw_exception(uri_error_ce, "Failed to update the query", 0); return FAILURE; } } @@ -457,7 +457,7 @@ static zend_result php_uri_parser_rfc3986_fragment_write(void *uri, zval *value, return FAILURE; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to update the fragment", 0); + zend_throw_exception(uri_error_ce, "Failed to update the fragment", 0); return FAILURE; } } @@ -484,7 +484,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to parse the specified URI", 0); + zend_throw_exception(uri_error_ce, "Failed to parse the specified URI", 0); break; } } @@ -506,7 +506,7 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str break; default: /* This should be unreachable in practice. */ - zend_throw_exception(uri_invalid_uri_exception_ce, "Failed to resolve the specified URI against the base URI", 0); + zend_throw_exception(uri_error_ce, "Failed to resolve the specified URI against the base URI", 0); break; } } From 5a6be795986afb95a1baaba0547aadaa095521b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 15 Sep 2025 22:02:40 +0200 Subject: [PATCH 3/5] uri: Throw `UriError` when unable to recompose URIs --- ext/uri/php_uri.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 021f3727b8dd1..c36d5f9b43c42 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -676,7 +676,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, withFragment) static void throw_cannot_recompose_uri_to_string(zend_object *object) { - zend_throw_exception_ex(NULL, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->ce->name)); + zend_throw_exception_ex(uri_error_ce, 0, "Cannot recompose %s to a string", ZSTR_VAL(object->ce->name)); } static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, zend_object *comparison_mode) From 6b7dfdba4545df31d3008ab6d4a2e54f4e3a0940 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Mon, 15 Sep 2025 22:02:54 +0200 Subject: [PATCH 4/5] uri: Throw `UriError` when unable to read component --- ext/uri/php_uri_common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c index efb7688a94502..c4ee94b4d5b98 100644 --- a/ext/uri/php_uri_common.c +++ b/ext/uri/php_uri_common.c @@ -52,7 +52,7 @@ void uri_read_component(INTERNAL_FUNCTION_PARAMETERS, php_uri_property_name prop const php_uri_property_handler *property_handler = php_uri_parser_property_handler_by_name(internal_uri->parser, property_name); if (UNEXPECTED(property_handler->read(internal_uri->uri, component_read_mode, return_value) == FAILURE)) { - zend_throw_error(NULL, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); + zend_throw_exception_ex(uri_error_ce, 0, "The %s component cannot be retrieved", ZSTR_VAL(get_known_string_by_property_name(property_name))); RETURN_THROWS(); } } From df8b26c2505a698493d1666843a9fccfb8923d4f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim=20D=C3=BCsterhus?= Date: Wed, 17 Sep 2025 19:07:25 +0200 Subject: [PATCH 5/5] NEWS --- NEWS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/NEWS b/NEWS index 42846ab7c5205..e2d6d9688b552 100644 --- a/NEWS +++ b/NEWS @@ -46,6 +46,8 @@ PHP NEWS (nielsdos) . Prevent modifying Uri\WhatWg\Url and Uri\Rfc3986\Uri objects by manually calling __construct() or __unserialize(). (timwolla) + . Add new Uri\UriError exception that is thrown for internal error + conditions. (timwolla) . Further clean up the internal API. (timwolla) - Windows: