Commit 2b9b40779a2 for php.net
commit 2b9b40779a2ad05a1eb164f86ac6327234f1003f
Author: Máté Kocsis <kocsismate@woohoolabs.com>
Date: Wed Sep 16 21:14:26 2026 +0200
ext/uri: Minor fixes for Uri\WhatWg\UrlBuilder
- Memory allocation errors would trigger an Error
- Various style fixes
- Test improvements
diff --git a/ext/uri/tests/whatwg/builder/build_success_soft_errors_reset.phpt b/ext/uri/tests/whatwg/builder/build_success_soft_errors_reset.phpt
index 4bfab1fd57e..80d0da8f5b0 100644
--- a/ext/uri/tests/whatwg/builder/build_success_soft_errors_reset.phpt
+++ b/ext/uri/tests/whatwg/builder/build_success_soft_errors_reset.phpt
@@ -10,6 +10,8 @@
$softErrors = [];
$builder->build(softErrors: $softErrors);
+var_dump($softErrors);
+
$builder->setFragment("ab");
$url = $builder->build(softErrors: $softErrors);
@@ -20,6 +22,17 @@
?>
--EXPECTF--
+array(1) {
+ [0]=>
+ object(Uri\WhatWg\UrlValidationError)#%d (%d) {
+ ["context"]=>
+ string(2) " b"
+ ["type"]=>
+ enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
+ ["failure"]=>
+ bool(false)
+ }
+}
string(23) "https://example.com/#ab"
object(Uri\WhatWg\Url)#%d (%d) {
["scheme"]=>
diff --git a/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt b/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt
new file mode 100644
index 00000000000..2f7549f4757
--- /dev/null
+++ b/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt
@@ -0,0 +1,34 @@
+--TEST--
+Test Uri\WhatWg\Url::__construct() - error - leaves soft errors unchanged
+--FILE--
+<?php
+
+$softErrors = ["unchanged"];
+
+try {
+ new Uri\WhatWg\Url("🐘", softErrors: $softErrors);
+} catch (Throwable $e) {
+ echo $e::class, ': ', $e->getMessage(), "\n";
+ var_dump($e->errors);
+}
+
+var_dump($softErrors);
+
+?>
+--EXPECTF--
+Uri\WhatWg\InvalidUrlException: The specified URI is malformed (MissingSchemeNonRelativeUrl)
+array(1) {
+ [0]=>
+ object(Uri\WhatWg\UrlValidationError)#%d (%d) {
+ ["context"]=>
+ string(4) "🐘"
+ ["type"]=>
+ enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl)
+ ["failure"]=>
+ bool(true)
+ }
+}
+array(1) {
+ [0]=>
+ string(9) "unchanged"
+}
diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c
index 0e5d9e8a66f..3ae5a3890e8 100644
--- a/ext/uri/uri_parser_whatwg.c
+++ b/ext/uri/uri_parser_whatwg.c
@@ -736,9 +736,9 @@ static void php_uri_parser_whatwg_destroy(void *uri)
lxb_url_destroy(lexbor_uri);
}
-ZEND_ATTRIBUTE_NONNULL static void php_uri_parser_whatwg_throw_exception(const char *message)
+ZEND_ATTRIBUTE_NONNULL static void php_uri_parser_whatwg_throw_exception(zend_class_entry *exception_ce, const char *message)
{
- zend_object *exception = zend_throw_exception(php_uri_ce_whatwg_invalid_url_exception, message, 0);
+ zend_object *exception = zend_throw_exception(exception_ce, message, 0);
zval errors;
ZVAL_EMPTY_ARRAY(&errors);
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), &errors);
@@ -993,7 +993,7 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2, 3, 4, 5, 6, 7, 8, 9) lxb_url_t *php_uri_parser_wh
lxb_url_t *lexbor_url = lexbor_mraw_calloc(lexbor_parser.mraw, sizeof(*lexbor_url));
if (lexbor_url == NULL) {
- php_uri_parser_whatwg_throw_exception("Memory allocation error");
+ php_uri_parser_whatwg_throw_exception(php_uri_ce_error, "Memory allocation error");
return NULL;
}
@@ -1026,17 +1026,17 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2, 3, 4, 5, 6, 7, 8, 9) lxb_url_t *php_uri_parser_wh
|| lexbor_url->host.type == LXB_URL_HOST_TYPE_EMPTY
|| lexbor_url->scheme.type == LXB_URL_SCHEMEL_TYPE_FILE) {
if (Z_TYPE_P(username) != IS_NULL) {
- php_uri_parser_whatwg_throw_exception("The specified URL cannot have username");
+ php_uri_parser_whatwg_throw_exception(php_uri_ce_whatwg_invalid_url_exception, "The specified URL cannot have username");
goto failure;
}
if (Z_TYPE_P(password) != IS_NULL) {
- php_uri_parser_whatwg_throw_exception("The specified URL cannot have password");
+ php_uri_parser_whatwg_throw_exception(php_uri_ce_whatwg_invalid_url_exception, "The specified URL cannot have password");
goto failure;
}
if (Z_TYPE_P(port) != IS_NULL) {
- php_uri_parser_whatwg_throw_exception("The specified URL cannot have port");
+ php_uri_parser_whatwg_throw_exception(php_uri_ce_whatwg_invalid_url_exception, "The specified URL cannot have port");
goto failure;
}
}
@@ -1075,10 +1075,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2, 3, 4, 5, 6, 7, 8, 9) lxb_url_t *php_uri_parser_wh
lexbor_str_init(&lexbor_url->query, lexbor_url->mraw, 1);
} else {
result = php_uri_parser_whatwg_query_write(lexbor_url, query, NULL);
- }
- php_uri_parser_whatwg_build_errors(&errors);
- if (result == FAILURE) {
- goto failure;
+ php_uri_parser_whatwg_build_errors(&errors);
+ if (result == FAILURE) {
+ goto failure;
+ }
}
if (Z_TYPE_P(fragment) == IS_STRING && Z_STRLEN_P(fragment) == 0) {
@@ -1088,10 +1088,10 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2, 3, 4, 5, 6, 7, 8, 9) lxb_url_t *php_uri_parser_wh
lexbor_str_init(&lexbor_url->fragment, lexbor_url->mraw, 1);
} else {
result = php_uri_parser_whatwg_fragment_write(lexbor_url, fragment, NULL);
- }
- php_uri_parser_whatwg_build_errors(&errors);
- if (result == FAILURE) {
- goto failure;
+ php_uri_parser_whatwg_build_errors(&errors);
+ if (result == FAILURE) {
+ goto failure;
+ }
}
if (lexbor_base_url != NULL) {
@@ -1107,16 +1107,17 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(2, 3, 4, 5, 6, 7, 8, 9) lxb_url_t *php_uri_parser_wh
return lexbor_url;
failure:
+ ZEND_ASSERT(EG(exception));
+
/* Include errors from earlier components in the exception raised by a later component. */
- if (zend_hash_num_elements(Z_ARRVAL(errors)) > 0 && EG(exception)
+ if (zend_hash_num_elements(Z_ARRVAL(errors)) > 0
&& instanceof_function(EG(exception)->ce, php_uri_ce_whatwg_invalid_url_exception)) {
zval rv;
zval *exception_errors = zend_read_property(php_uri_ce_whatwg_invalid_url_exception,
EG(exception), ZEND_STRL("errors"), true, &rv);
ZEND_ASSERT(Z_TYPE_P(exception_errors) == IS_ARRAY);
- zval *error;
- ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(exception_errors), error) {
+ ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(exception_errors), zval *error) {
Z_TRY_ADDREF_P(error);
zend_hash_next_index_insert(Z_ARRVAL(errors), error);
} ZEND_HASH_FOREACH_END();