Commit fe0263f3445 for php.net
commit fe0263f3445ec48bbac56c43720629c9bf4700dc
Author: Tim Düsterhus <tim@bastelstu.be>
Date: Wed Sep 17 19:46:19 2025 +0200
uri: Throw `UriError` for unexpected failures (#19850)
* uri: Add `UriError`
* 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.
* uri: Throw `UriError` when unable to recompose URIs
* uri: Throw `UriError` when unable to read component
* NEWS
diff --git a/NEWS b/NEWS
index 42846ab7c52..e2d6d9688b5 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:
diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c
index e5436d7f1e3..c36d5f9b43c 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;
@@ -675,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)
@@ -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 b4063bee8f5..9f12fbb1c07 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 12a498357ea..602e996b1a2 100644
Binary files a/ext/uri/php_uri_arginfo.h and b/ext/uri/php_uri_arginfo.h differ
diff --git a/ext/uri/php_uri_common.c b/ext/uri/php_uri_common.c
index efb7688a945..c4ee94b4d5b 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();
}
}
diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h
index f061db6f981..ba5b0b2d7ee 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;
diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c
index 583d3b9f5e0..c60c86efbfc 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;
}
}