Browse Source

Fix GH-19780: InvalidUrlException should check $errors argument (#19781)

It makes sense to restrict the types used for $errors.
This can also improve the types for static analysis tools as they can
now rely on the array being a list of this class type.

Closes GH-19781.
pull/19783/head
Niels Dossche 1 month ago
committed by GitHub
parent
commit
834e92a4f3
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 4
      NEWS
  2. 26
      ext/uri/php_uri.c
  3. 29
      ext/uri/tests/gh19780.phpt

4
NEWS

@ -6,6 +6,10 @@ PHP NEWS
. Fixed bug GH-19765 (object_properties_load() bypasses readonly property
checks). (timwolla)
- URI:
. Fixed bug GH-19780 (InvalidUrlException should check $errors argument).
(nielsdos)
11 Sep 2025, PHP 8.5.0beta3
- Core:

26
ext/uri/php_uri.c

@ -391,6 +391,27 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, uri_str, base_url_object, is_constructor, is_constructor, NULL);
}
static bool is_list_of_whatwg_validation_errors(const HashTable *array)
{
if (!zend_array_is_list(array)) {
return false;
}
ZEND_HASH_FOREACH_VAL(array, zval *val) {
/* Do not allow references as they may change types after checking. */
if (Z_TYPE_P(val) != IS_OBJECT) {
return false;
}
if (!instanceof_function(Z_OBJCE_P(val), uri_whatwg_url_validation_error_ce)) {
return false;
}
} ZEND_HASH_FOREACH_END();
return true;
}
PHP_METHOD(Uri_Rfc3986_Uri, parse)
{
create_rfc3986_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, false);
@ -425,6 +446,11 @@ PHP_METHOD(Uri_WhatWg_InvalidUrlException, __construct)
ZVAL_EMPTY_ARRAY(&tmp);
zend_update_property(uri_whatwg_invalid_url_exception_ce, 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));
RETURN_THROWS();
}
zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(ZEND_THIS), ZEND_STRL("errors"), errors);
}
if (EG(exception)) {

29
ext/uri/tests/gh19780.phpt

@ -0,0 +1,29 @@
--TEST--
GH-19780 (InvalidUrlException should check $errors argument)
--EXTENSIONS--
uri
--FILE--
<?php
use Uri\WhatWg\InvalidUrlException;
use Uri\WhatWg\UrlValidationError;
use Uri\WhatWg\UrlValidationErrorType;
try {
new InvalidUrlException('message', ['foo']);
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
try {
new InvalidUrlException('message', [
1 => new UrlValidationError('context', UrlValidationErrorType::HostMissing, true)
]);
} catch (ValueError $e) {
echo $e->getMessage(), "\n";
}
?>
--EXPECT--
Uri\WhatWg\InvalidUrlException::__construct(): Argument #2 ($errors) must be a list of Uri\WhatWg\UrlValidationError
Uri\WhatWg\InvalidUrlException::__construct(): Argument #2 ($errors) must be a list of Uri\WhatWg\UrlValidationError
Loading…
Cancel
Save