Commit c67088d46e8 for php.net
commit c67088d46e802e7e8576c52b76cd50f9ae77680b
Author: Máté Kocsis <kocsismate@woohoolabs.com>
Date: Sun Sep 20 08:09:09 2026 +0200
ext/uri: Fix the behavior for $softErrors (#23740)
Uri\WhatWg\Url::__construct() and Uri\WhatWg\UrlBuilder::build() now set $softErrors to an empty array when URL processing throws an exception, instead of preserving its value.
diff --git a/UPGRADING b/UPGRADING
index f2a2ef8f5e7..a8ae2045f89 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -318,6 +318,12 @@ PHP 8.6 UPGRADE NOTES
platform's key_t range instead of passing a truncated key to the operating
system.
+- URI:
+ . Uri\WhatWg\Url::__construct() now sets $softErrors to an empty array when
+ URL processing throws an exception, instead of preserving its value.
+ URL validation errors remain available in the
+ Uri\WhatWg\InvalidUrlException::$errors property.
+
- Zip:
. ZipArchive::extractTo now raises a TypeError for the files argument if one
or more of the entries is not a string.
diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c
index 9d6e58dc181..aab94e94618 100644
--- a/ext/uri/php_uri.c
+++ b/ext/uri/php_uri.c
@@ -387,6 +387,8 @@ ZEND_ATTRIBUTE_NONNULL_ARGS(1, 2) PHPAPI void php_uri_instantiate_uri(
if (UNEXPECTED(uri == NULL)) {
if (should_throw) {
zval_ptr_dtor(&errors);
+ ZVAL_EMPTY_ARRAY(&errors);
+ pass_errors_by_ref_and_free(errors_zv, &errors);
RETURN_THROWS();
} else {
if (pass_errors_by_ref_and_free(errors_zv, &errors) == FAILURE) {
@@ -1433,6 +1435,9 @@ PHP_METHOD(Uri_WhatWg_UrlBuilder, build)
soft_errors
);
if (lexbor_url == NULL) {
+ zval errors;
+ ZVAL_EMPTY_ARRAY(&errors);
+ pass_errors_by_ref_and_free(soft_errors, &errors);
RETURN_THROWS();
}
diff --git a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_password.phpt b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_password.phpt
index 76a170f4e26..f81ba3a518b 100644
--- a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_password.phpt
+++ b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_password.phpt
@@ -7,17 +7,14 @@
$builder->setScheme("foo");
$builder->setHost("\t\n");
$builder->setPassword("pass");
-$softErrors = ["unchanged"];
try {
- $builder->build(softErrors: $softErrors);
+ $builder->build();
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
var_dump($e->errors);
}
-var_dump($softErrors);
-
?>
--EXPECTF--
Uri\WhatWg\InvalidUrlException: The specified URL cannot have password
@@ -33,7 +30,3 @@ enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
bool(false)
}
}
-array(1) {
- [0]=>
- string(9) "unchanged"
-}
diff --git a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_port.phpt b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_port.phpt
index 6b63a86d2ee..903e14dd75b 100644
--- a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_port.phpt
+++ b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_port.phpt
@@ -7,17 +7,14 @@
$builder->setScheme("foo");
$builder->setHost("\t\n");
$builder->setPort(123);
-$softErrors = ["unchanged"];
try {
- $builder->build(softErrors: $softErrors);
+ $builder->build();
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
var_dump($e->errors);
}
-var_dump($softErrors);
-
?>
--EXPECTF--
Uri\WhatWg\InvalidUrlException: The specified URL cannot have port
@@ -33,7 +30,3 @@ enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
bool(false)
}
}
-array(1) {
- [0]=>
- string(9) "unchanged"
-}
diff --git a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_username.phpt b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_username.phpt
index 534271bd29e..0189c8ff161 100644
--- a/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_username.phpt
+++ b/ext/uri/tests/whatwg/builder/build_error_normalized_empty_host_username.phpt
@@ -7,17 +7,14 @@
$builder->setScheme("foo");
$builder->setHost("\t\n");
$builder->setUsername("user");
-$softErrors = ["unchanged"];
try {
- $builder->build(softErrors: $softErrors);
+ $builder->build();
} catch (Throwable $e) {
echo $e::class, ': ', $e->getMessage(), "\n";
var_dump($e->errors);
}
-var_dump($softErrors);
-
?>
--EXPECTF--
Uri\WhatWg\InvalidUrlException: The specified URL cannot have username
@@ -33,7 +30,3 @@ enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
bool(false)
}
}
-array(1) {
- [0]=>
- string(9) "unchanged"
-}
diff --git a/ext/uri/tests/whatwg/builder/build_error_soft_errors_unchanged.phpt b/ext/uri/tests/whatwg/builder/build_error_soft_errors_reset.phpt
similarity index 84%
rename from ext/uri/tests/whatwg/builder/build_error_soft_errors_unchanged.phpt
rename to ext/uri/tests/whatwg/builder/build_error_soft_errors_reset.phpt
index 5cba13e51c1..f43ab31164b 100644
--- a/ext/uri/tests/whatwg/builder/build_error_soft_errors_unchanged.phpt
+++ b/ext/uri/tests/whatwg/builder/build_error_soft_errors_reset.phpt
@@ -1,12 +1,12 @@
--TEST--
-Test Uri\WhatWg\UrlBuilder::build() - error - leaves soft errors unchanged
+Test Uri\WhatWg\UrlBuilder::build() - error - clears soft errors when an exception is thrown
--FILE--
<?php
$builder = new Uri\WhatWg\UrlBuilder();
$builder->setScheme("ht\ttps");
$builder->setHost(null);
-$softErrors = ["unchanged"];
+$softErrors = ["previous error"];
try {
$builder->build(softErrors: $softErrors);
@@ -40,7 +40,5 @@ enum(Uri\WhatWg\UrlValidationErrorType::HostMissing)
bool(true)
}
}
-array(1) {
- [0]=>
- string(9) "unchanged"
+array(0) {
}
diff --git a/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt b/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_reset.phpt
similarity index 79%
rename from ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt
rename to ext/uri/tests/whatwg/parsing/basic_error_soft_errors_reset.phpt
index 2f7549f4757..36eaaec426a 100644
--- a/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_unchanged.phpt
+++ b/ext/uri/tests/whatwg/parsing/basic_error_soft_errors_reset.phpt
@@ -1,9 +1,9 @@
--TEST--
-Test Uri\WhatWg\Url::__construct() - error - leaves soft errors unchanged
+Test Uri\WhatWg\Url::__construct() - error - clears soft errors when an exception is thrown
--FILE--
<?php
-$softErrors = ["unchanged"];
+$softErrors = ["previous error"];
try {
new Uri\WhatWg\Url("🐘", softErrors: $softErrors);
@@ -28,7 +28,5 @@ enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl)
bool(true)
}
}
-array(1) {
- [0]=>
- string(9) "unchanged"
+array(0) {
}