From 5dd39094226e9dffe7a59fc70f60032751eae66e Mon Sep 17 00:00:00 2001 From: David Carlier Date: Fri, 22 May 2026 06:15:44 +0100 Subject: [PATCH 1/5] Fix GH-19739: imageellipse/imagefilledellipse overflow. Port the upstream libgd portable fix (overflowMul3) for the int64 overflow at r = a * bq when w/h reach near INT_MAX. Mirrors the upstream libgd commit 0057de6. close GH-22116 --- NEWS | 2 ++ ext/gd/libgd/gd.c | 7 ++++++- ext/gd/libgd/gd_security.c | 18 ++++++++++++++++++ ext/gd/libgd/gdhelpers.h | 1 + ext/gd/tests/gh19739.phpt | 18 ++++++++++++++++++ 5 files changed, 45 insertions(+), 1 deletion(-) create mode 100644 ext/gd/tests/gh19739.phpt diff --git a/NEWS b/NEWS index db03aa98c3a1..3899aea32cab 100644 --- a/NEWS +++ b/NEWS @@ -7,6 +7,8 @@ PHP NEWS overflow-triggered early return). (iliaal) . Fixed bug GH-19666 (imageconvolution() unexpected nan filter value). (David Carlier) + . Fixed bug GH-19739 (imageellipse/imagefilledellipse overflow). + (David Carlier) - Intl: . Fix incorrect argument positions for uninitialized calendar arguments in diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index 0ab26647c1d3..7a2692436a1e 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -1775,6 +1775,9 @@ void gdImageEllipse(gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } gdImageSetPixel(im,mx+a, my, c); gdImageSetPixel(im,mx-a, my, c); mx1 = mx-a;my1 = my; @@ -1816,7 +1819,9 @@ void gdImageFilledEllipse (gdImagePtr im, int mx, int my, int w, int h, int c) a=w>>1; b=h>>1; - + if (overflowMul3(a, b, b) || overflowMul3(b, a, a)) { + return; + } for (x = mx-a; x <= mx+a; x++) { gdImageSetPixel(im, x, my, c); } diff --git a/ext/gd/libgd/gd_security.c b/ext/gd/libgd/gd_security.c index 438a564ff17c..cbc4872d2fce 100644 --- a/ext/gd/libgd/gd_security.c +++ b/ext/gd/libgd/gd_security.c @@ -14,6 +14,7 @@ #include #include +#include #include #include "gd.h" #include "gd_errors.h" @@ -30,3 +31,20 @@ int overflow2(int a, int b) } return 0; } + +int overflowMul3(int a, int b, int c) +{ + if (a < 0 || b < 0 || c < 0) { + return 1; + } + if (a == 0 || b == 0 || c == 0) { + return 0; + } + if (a > INT_MAX / b) { + return 1; + } + if ((int64_t)a * b > INT64_MAX / c) { + return 1; + } + return 0; +} diff --git a/ext/gd/libgd/gdhelpers.h b/ext/gd/libgd/gdhelpers.h index afb45f0e67de..202ccfce7636 100644 --- a/ext/gd/libgd/gdhelpers.h +++ b/ext/gd/libgd/gdhelpers.h @@ -27,6 +27,7 @@ extern char *gd_strtok_r(char *s, char *sep, char **state); netpbm fixes by Alan Cox. */ int overflow2(int a, int b); +int overflowMul3(int a, int b, int c); #ifdef ZTS #define gdMutexDeclare(x) MUTEX_T x diff --git a/ext/gd/tests/gh19739.phpt b/ext/gd/tests/gh19739.phpt new file mode 100644 index 000000000000..7dce387b780e --- /dev/null +++ b/ext/gd/tests/gh19739.phpt @@ -0,0 +1,18 @@ +--TEST-- +GH-19739 (integer overflow in imageellipse / imagefilledellipse) +--EXTENSIONS-- +gd +--FILE-- + +--EXPECT-- +bool(true) +bool(true) +done From 27d7b799c0a13578ee0506b428b8ddc209ffb010 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sun, 24 May 2026 22:37:38 +0200 Subject: [PATCH 2/5] Add lxb_url_is_special to the public API of Lexbor (#22093) It's needed to implement https://github.com/php/php-src/pull/22075 for https://wiki.php.net/rfc/uri_followup#uri_type_detection. Since the upstream changes to lexbor (https://github.com/lexbor/lexbor/pull/362) haven't been released yet, a patch is added for now. --- ext/lexbor/lexbor/url/url.c | 2 +- ext/lexbor/lexbor/url/url.h | 9 ++++ .../0007-Add-Is_Special_Url_Support.patch | 44 +++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch diff --git a/ext/lexbor/lexbor/url/url.c b/ext/lexbor/lexbor/url/url.c index 5a1143469d1a..a5b323f2df09 100644 --- a/ext/lexbor/lexbor/url/url.c +++ b/ext/lexbor/lexbor/url/url.c @@ -860,7 +860,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; } -lxb_inline bool +bool lxb_url_is_special(const lxb_url_t *url) { return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; diff --git a/ext/lexbor/lexbor/url/url.h b/ext/lexbor/lexbor/url/url.h index 4ed3f32aa646..6cc6f1081c8a 100644 --- a/ext/lexbor/lexbor/url/url.h +++ b/ext/lexbor/lexbor/url/url.h @@ -763,6 +763,15 @@ LXB_API lxb_status_t lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, lexbor_callback_f cb, void *ctx); +/** + * Returns whether the URL is special. + * + * @param[in] lxb_url_t *. Cannot be NULL. + * @return true if URL is special, false otherwise. + */ +LXB_API bool +lxb_url_is_special(const lxb_url_t *url); + /* * Inline functions. */ diff --git a/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch b/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch new file mode 100644 index 000000000000..6f5e126336d0 --- /dev/null +++ b/ext/lexbor/patches/0007-Add-Is_Special_Url_Support.patch @@ -0,0 +1,44 @@ +From 9181fce509ab9b37c02994545f3971687433e770 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= +Date: Sun, 17 May 2026 22:17:14 +0200 +Subject: [PATCH] Add lxb_url_is_special() to the public API (#362) + +As https://wiki.php.net/rfc/uri_followup#uri_type_detection relies on this information. +--- + source/lexbor/url/url.c | 2 +- + source/lexbor/url/url.h | 9 +++++++++ + 2 files changed, 10 insertions(+), 1 deletion(-) + +diff --git a/source/lexbor/url/url.c b/source/lexbor/url/url.c +index 5a114346..a5b323f2 100644 +--- a/source/lexbor/url/url.c ++++ b/source/lexbor/url/url.c +@@ -860,7 +860,7 @@ lxb_url_is_url_codepoint(lxb_codepoint_t cp) + return lxb_url_codepoint_alphanumeric[(lxb_char_t) cp] != 0xFF; + } + +-lxb_inline bool ++bool + lxb_url_is_special(const lxb_url_t *url) + { + return url->scheme.type != LXB_URL_SCHEMEL_TYPE__UNKNOWN; +diff --git a/source/lexbor/url/url.h b/source/lexbor/url/url.h +index 4ed3f32a..6cc6f108 100644 +--- a/source/lexbor/url/url.h ++++ b/source/lexbor/url/url.h +@@ -763,6 +763,15 @@ LXB_API lxb_status_t + lxb_url_search_params_serialize(lxb_url_search_params_t *search_params, + lexbor_callback_f cb, void *ctx); + ++/** ++ * Returns whether the URL is special. ++ * ++ * @param[in] lxb_url_t *. Cannot be NULL. ++ * @return true if URL is special, false otherwise. ++ */ ++LXB_API bool ++lxb_url_is_special(const lxb_url_t *url); ++ + /* + * Inline functions. + */ \ No newline at end of file From f58b95ef5958ae5f18d62874e5419bc2810508cb Mon Sep 17 00:00:00 2001 From: Sebastian Bergmann Date: Sun, 24 May 2026 23:21:07 +0200 Subject: [PATCH 3/5] ini_get_all(): Add `builtin_default_value` column (#22134) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes GH-22133. Co-authored-by: Tim Düsterhus --- NEWS | 2 ++ UPGRADING | 6 ++++ ext/standard/basic_functions.c | 6 ++++ .../tests/general_functions/ini_get_all.phpt | 12 +++++-- .../ini_get_all_builtin_default_value.phpt | 33 +++++++++++++++++++ ...ni_get_all_builtin_default_value_null.phpt | 33 +++++++++++++++++++ 6 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt create mode 100644 ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt diff --git a/NEWS b/NEWS index d5e3f6d71b93..4caae2db920f 100644 --- a/NEWS +++ b/NEWS @@ -224,6 +224,8 @@ PHP NEWS null bytes. (Weilin Du) . proc_open() now raises a ValueError when the $cwd argument contains null bytes. (Weilin Du) + . ini_get_all() now includes the built-in default value in the details. + (sebastian) - Streams: . Added so_keepalive, tcp_keepidle, tcp_keepintvl and tcp_keepcnt stream diff --git a/UPGRADING b/UPGRADING index 7f805496db74..f2b6303a923e 100644 --- a/UPGRADING +++ b/UPGRADING @@ -270,6 +270,12 @@ PHP 8.6 UPGRADE NOTES when not null, and on failure, gives the error code (one of the EAI_* constants). +- Standard: + . ini_get_all() now includes a "builtin_default_value" element for each + directive when $details is true. It holds the built-in default value of + the directive (or null if it has none), independent of values set in + php.ini, on the command line, or at runtime. + ======================================== 6. New Functions ======================================== diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 29ed6ddf14e9..2a0e7a786738 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1955,6 +1955,12 @@ PHP_FUNCTION(ini_get_all) add_assoc_null(&option, "local_value"); } + if (ini_entry->def->value) { + add_assoc_stringl(&option, "builtin_default_value", ini_entry->def->value, ini_entry->def->value_length); + } else { + add_assoc_null(&option, "builtin_default_value"); + } + add_assoc_long(&option, "access", ini_entry->modifiable); zend_symtable_update(Z_ARRVAL_P(return_value), ini_entry->name, &option); diff --git a/ext/standard/tests/general_functions/ini_get_all.phpt b/ext/standard/tests/general_functions/ini_get_all.phpt index 2b71b474a013..c54b39ac3325 100644 --- a/ext/standard/tests/general_functions/ini_get_all.phpt +++ b/ext/standard/tests/general_functions/ini_get_all.phpt @@ -33,29 +33,35 @@ array(0) { } array(3) { ["pcre.backtrack_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(7) "1000000" ["local_value"]=> string(7) "1000000" + ["builtin_default_value"]=> + string(7) "1000000" ["access"]=> int(7) } ["pcre.jit"]=> - array(3) { + array(4) { ["global_value"]=> string(1) "1" ["local_value"]=> string(1) "1" + ["builtin_default_value"]=> + string(1) "1" ["access"]=> int(7) } ["pcre.recursion_limit"]=> - array(3) { + array(4) { ["global_value"]=> string(6) "100000" ["local_value"]=> string(6) "100000" + ["builtin_default_value"]=> + string(6) "100000" ["access"]=> int(7) } diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt new file mode 100644 index 000000000000..82de8781caa7 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() exposes the built-in default value independent of configuration and runtime changes +--INI-- +precision=8 +--FILE-- + +--EXPECT-- +string(1) "8" +string(1) "8" +string(2) "14" +string(1) "8" +string(1) "3" +string(2) "14" +Done diff --git a/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt new file mode 100644 index 000000000000..efd86eb947e4 --- /dev/null +++ b/ext/standard/tests/general_functions/ini_get_all_builtin_default_value_null.phpt @@ -0,0 +1,33 @@ +--TEST-- +ini_get_all() reports a null built-in default value for a directive that has no compiled-in default +--INI-- +error_append_string=FOO +--FILE-- + +--EXPECT-- +string(3) "FOO" +string(3) "FOO" +NULL +string(3) "FOO" +string(3) "BAR" +NULL +Done From 1bf64cee9387bec1fdee84e57ff74bea79311aad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sun, 24 May 2026 23:35:44 +0200 Subject: [PATCH 4/5] Implement "Followup improvements for ext/uri" RFC - URI type detection (#22075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection --------- Co-authored-by: Tim Düsterhus --- NEWS | 4 +++ UPGRADING | 4 +++ ext/uri/php_uri.c | 23 ++++++++++++++ ext/uri/php_uri.stub.php | 12 +++++++ ext/uri/php_uri_arginfo.h | 27 +++++++++++++++- ext/uri/php_uri_common.h | 1 + ext/uri/php_uri_decl.h | 15 ++++++--- ..._type_success_absolute_path_reference.phpt | 12 +++++++ ...i_type_success_network_path_reference.phpt | 12 +++++++ ..._type_success_relative_path_reference.phpt | 12 +++++++ .../getters/uri_type_success_uri_basic.phpt | 12 +++++++ .../uri_type_success_uri_empty_authority.phpt | 12 +++++++ .../uri_type_success_uri_no_authority.phpt | 12 +++++++ .../is_special_scheme_success_false.phpt | 12 +++++++ .../is_special_scheme_success_true.phpt | 31 +++++++++++++++++++ ext/uri/uri_parser_rfc3986.c | 20 ++++++++++++ ext/uri/uri_parser_rfc3986.h | 2 ++ ext/uri/uri_parser_whatwg.c | 5 +++ ext/uri/uri_parser_whatwg.h | 2 ++ 19 files changed, 225 insertions(+), 5 deletions(-) create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt create mode 100644 ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt create mode 100644 ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt create mode 100644 ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt diff --git a/NEWS b/NEWS index 4caae2db920f..bb873c2619da 100644 --- a/NEWS +++ b/NEWS @@ -241,6 +241,10 @@ PHP NEWS . Fixed bug #49874 (ftell() and fseek() inconsistency when using stream filters). (Jakub Zelenka) +- URI: + . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). + (kocsismate) + - Zip: . Fixed ZipArchive callback being called after executor has shut down. (ilutov) diff --git a/UPGRADING b/UPGRADING index f2b6303a923e..38858a27ea9d 100644 --- a/UPGRADING +++ b/UPGRADING @@ -211,6 +211,10 @@ PHP 8.6 UPGRADE NOTES options. . Allowed casting casting filtered streams as file descriptor for select. +- URI: + . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). + RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection + ======================================== 3. Changes in SAPI modules ======================================== diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 4cf6e970b07e..007517ae04d9 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -31,6 +31,7 @@ #include "uriparser/Uri.h" zend_class_entry *php_uri_ce_rfc3986_uri; +zend_class_entry *php_uri_ce_rfc3986_uri_type; zend_class_entry *php_uri_ce_whatwg_url; zend_class_entry *php_uri_ce_comparison_mode; zend_class_entry *php_uri_ce_exception; @@ -508,6 +509,16 @@ PHP_METHOD(Uri_WhatWg_Url, __construct) create_whatwg_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, true); } +PHP_METHOD(Uri_Rfc3986_Uri, getUriType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_rfc3986_uri_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_Rfc3986_Uri, getScheme) { php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_ASCII); @@ -883,6 +894,16 @@ PHP_METHOD(Uri_WhatWg_Url, withScheme) php_uri_property_write_str_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_SCHEME); } +PHP_METHOD(Uri_WhatWg_Url, isSpecialScheme) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + RETVAL_BOOL(php_uri_parser_whatwg_is_special(uri_object->uri)); +} + PHP_METHOD(Uri_WhatWg_Url, withUsername) { php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_USERNAME); @@ -1078,6 +1099,8 @@ static PHP_MINIT_FUNCTION(uri) object_handlers_rfc3986_uri.free_obj = php_uri_object_handler_free; object_handlers_rfc3986_uri.clone_obj = php_uri_object_handler_clone; + php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType(); + php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url(); php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg; php_uri_ce_whatwg_url->default_object_handlers = &object_handlers_whatwg_uri; diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index 6d4b2c3517a5..03e8a483b0b3 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -29,6 +29,14 @@ enum UriComparisonMode } namespace Uri\Rfc3986 { + enum UriType + { + case AbsolutePathReference; + case RelativePathReference; + case NetworkPathReference; + case Uri; + } + /** @strict-properties */ final readonly class Uri { @@ -36,6 +44,8 @@ public static function parse(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null): ?s public function __construct(string $uri, ?\Uri\Rfc3986\Uri $baseUrl = null) {} + public function getUriType(): ?\Uri\Rfc3986\UriType {} + public function getScheme(): ?string {} public function getRawScheme(): ?string {} @@ -165,6 +175,8 @@ public function getScheme(): string {} public function withScheme(string $scheme): static {} + public function isSpecialScheme(): bool {} + /** @implementation-alias Uri\Rfc3986\Uri::getUsername */ public function getUsername(): ?string {} diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 18d7f4adf783..e88d439fa16a 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 php_uri.stub.php instead. - * Stub hash: 3c228f4227e7543be5c12c99074789d92c27ab99 + * Stub hash: 4143e681e589d6e663f3f7d9eb7677cd3395baf2 * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_parse, 0, 1, IS_STATIC, 1) @@ -12,6 +12,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Uri_Rfc3986_Uri___construct, 0, 0, 1) ZEND_ARG_OBJ_INFO_WITH_DEFAULT_VALUE(0, baseUrl, Uri\\Rfc3986\\\125ri, 1, "null") ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getUriType, 0, 0, Uri\\Rfc3986\\\125riType, 1) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getScheme, 0, 0, IS_STRING, 1) ZEND_END_ARG_INFO() @@ -130,6 +133,9 @@ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withScheme, ZEND_ARG_TYPE_INFO(0, scheme, IS_STRING, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_isSpecialScheme, 0, 0, _IS_BOOL, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_Uri_WhatWg_Url_getUsername arginfo_class_Uri_Rfc3986_Uri_getScheme ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_WhatWg_Url_withUsername, 0, 1, IS_STATIC, 0) @@ -186,6 +192,7 @@ ZEND_END_ARG_INFO() ZEND_METHOD(Uri_Rfc3986_Uri, parse); ZEND_METHOD(Uri_Rfc3986_Uri, __construct); +ZEND_METHOD(Uri_Rfc3986_Uri, getUriType); ZEND_METHOD(Uri_Rfc3986_Uri, getScheme); ZEND_METHOD(Uri_Rfc3986_Uri, getRawScheme); ZEND_METHOD(Uri_Rfc3986_Uri, withScheme); @@ -223,6 +230,7 @@ ZEND_METHOD(Uri_WhatWg_Url, parse); ZEND_METHOD(Uri_WhatWg_Url, __construct); ZEND_METHOD(Uri_WhatWg_Url, getScheme); ZEND_METHOD(Uri_WhatWg_Url, withScheme); +ZEND_METHOD(Uri_WhatWg_Url, isSpecialScheme); ZEND_METHOD(Uri_WhatWg_Url, withUsername); ZEND_METHOD(Uri_WhatWg_Url, withPassword); ZEND_METHOD(Uri_WhatWg_Url, getAsciiHost); @@ -238,6 +246,7 @@ ZEND_METHOD(Uri_WhatWg_Url, __debugInfo); static const zend_function_entry class_Uri_Rfc3986_Uri_methods[] = { ZEND_ME(Uri_Rfc3986_Uri, parse, arginfo_class_Uri_Rfc3986_Uri_parse, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) ZEND_ME(Uri_Rfc3986_Uri, __construct, arginfo_class_Uri_Rfc3986_Uri___construct, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getUriType, arginfo_class_Uri_Rfc3986_Uri_getUriType, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getScheme, arginfo_class_Uri_Rfc3986_Uri_getScheme, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getRawScheme, arginfo_class_Uri_Rfc3986_Uri_getRawScheme, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, withScheme, arginfo_class_Uri_Rfc3986_Uri_withScheme, ZEND_ACC_PUBLIC) @@ -287,6 +296,7 @@ static const zend_function_entry class_Uri_WhatWg_Url_methods[] = { ZEND_ME(Uri_WhatWg_Url, __construct, arginfo_class_Uri_WhatWg_Url___construct, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getScheme, arginfo_class_Uri_WhatWg_Url_getScheme, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, withScheme, arginfo_class_Uri_WhatWg_Url_withScheme, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_WhatWg_Url, isSpecialScheme, arginfo_class_Uri_WhatWg_Url_isSpecialScheme, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("getUsername", zim_Uri_Rfc3986_Uri_getUsername, arginfo_class_Uri_WhatWg_Url_getUsername, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_ME(Uri_WhatWg_Url, withUsername, arginfo_class_Uri_WhatWg_Url_withUsername, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("getPassword", zim_Uri_Rfc3986_Uri_getPassword, arginfo_class_Uri_WhatWg_Url_getPassword, ZEND_ACC_PUBLIC, NULL, NULL) @@ -353,6 +363,21 @@ static zend_class_entry *register_class_Uri_UriComparisonMode(void) return class_entry; } +static zend_class_entry *register_class_Uri_Rfc3986_UriType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\Rfc3986\\UriType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "AbsolutePathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "RelativePathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "NetworkPathReference", NULL); + + zend_enum_add_case_cstr(class_entry, "Uri", NULL); + + return class_entry; +} + static zend_class_entry *register_class_Uri_Rfc3986_Uri(void) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 65e9cff89a15..4c0ac466da78 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -18,6 +18,7 @@ #include "php_uri_decl.h" extern zend_class_entry *php_uri_ce_rfc3986_uri; +extern zend_class_entry *php_uri_ce_rfc3986_uri_type; extern zend_class_entry *php_uri_ce_whatwg_url; extern zend_class_entry *php_uri_ce_comparison_mode; extern zend_class_entry *php_uri_ce_exception; diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h index 3c069f3abe6d..947858515dbb 100644 --- a/ext/uri/php_uri_decl.h +++ b/ext/uri/php_uri_decl.h @@ -1,14 +1,21 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: 3c228f4227e7543be5c12c99074789d92c27ab99 */ + * Stub hash: 4143e681e589d6e663f3f7d9eb7677cd3395baf2 */ -#ifndef ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H -#define ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H +#ifndef ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H +#define ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H typedef enum zend_enum_Uri_UriComparisonMode { ZEND_ENUM_Uri_UriComparisonMode_IncludeFragment = 1, ZEND_ENUM_Uri_UriComparisonMode_ExcludeFragment = 2, } zend_enum_Uri_UriComparisonMode; +typedef enum zend_enum_Uri_Rfc3986_UriType { + ZEND_ENUM_Uri_Rfc3986_UriType_AbsolutePathReference = 1, + ZEND_ENUM_Uri_Rfc3986_UriType_RelativePathReference = 2, + ZEND_ENUM_Uri_Rfc3986_UriType_NetworkPathReference = 3, + ZEND_ENUM_Uri_Rfc3986_UriType_Uri = 4, +} zend_enum_Uri_Rfc3986_UriType; + typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToAscii = 1, ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToUnicode = 2, @@ -41,4 +48,4 @@ typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_FileInvalidWindowsDriveLetterHost = 29, } zend_enum_Uri_WhatWg_UrlValidationErrorType; -#endif /* ZEND_PHP_URI_DECL_3c228f4227e7543be5c12c99074789d92c27ab99_H */ +#endif /* ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H */ diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt new file mode 100644 index 000000000000..1cddc15fa33c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_absolute_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Absolute path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::AbsolutePathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt new file mode 100644 index 000000000000..d7debc5ba66c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_network_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Network path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::NetworkPathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt new file mode 100644 index 000000000000..6cb51405f925 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_relative_path_reference.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - Relative path reference +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::RelativePathReference) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt new file mode 100644 index 000000000000..262300103f9c --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_basic.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt new file mode 100644 index 000000000000..ad8f2f27a8c6 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_empty_authority.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI with empty authority +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt new file mode 100644 index 000000000000..e266502ce90e --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/uri_type_success_uri_no_authority.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri getter - uri type - URI without authority +--FILE-- +getUriType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriType::Uri) diff --git a/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt b/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt new file mode 100644 index 000000000000..9bbb85755843 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/is_special_scheme_success_false.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url::isSpecialScheme() - success - not special +--FILE-- +isSpecialScheme()); + +?> +--EXPECT-- +bool(false) diff --git a/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt b/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt new file mode 100644 index 000000000000..1e19641b5600 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/is_special_scheme_success_true.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test Uri\WhatWg\Url::isSpecialScheme() - success - special +--FILE-- +isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("https://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("ws://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("wss://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("ftp://example.com"); +var_dump($url->isSpecialScheme()); + +$url = Uri\WhatWg\Url::parse("file://example.com"); +var_dump($url->isSpecialScheme()); + +?> +--EXPECT-- +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 172d7f08f144..cdf88013252f 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -15,6 +15,7 @@ #include "php.h" #include "uri_parser_rfc3986.h" #include "php_uri_common.h" +#include "Zend/zend_enum.h" #include "Zend/zend_smart_str.h" #include "Zend/zend_exceptions.h" @@ -110,6 +111,25 @@ ZEND_ATTRIBUTE_NONNULL static UriUriA *get_uri_for_writing(php_uri_parser_rfc398 return &uriparser_uris->uri; } +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_uri_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval) +{ + const UriUriA *uriparser_uri = get_uri_for_reading(uri, PHP_URI_COMPONENT_READ_MODE_RAW); + + const char *type; + + if (has_text_range(&uriparser_uri->scheme)) { + type = "Uri"; + } else if (has_text_range(&uriparser_uri->hostText)) { + type = "NetworkPathReference"; + } else if (uriparser_uri->absolutePath) { + type = "AbsolutePathReference"; + } else { + type = "RelativePathReference"; + } + + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_rfc3986_uri_type, type)); +} + ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_scheme_read(void *uri, php_uri_component_read_mode read_mode, zval *retval) { const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); diff --git a/ext/uri/uri_parser_rfc3986.h b/ext/uri/uri_parser_rfc3986.h index 21f938c370ad..bf8a0733fc8a 100644 --- a/ext/uri/uri_parser_rfc3986.h +++ b/ext/uri/uri_parser_rfc3986.h @@ -21,6 +21,8 @@ PHPAPI extern const php_uri_parser php_uri_parser_rfc3986; typedef struct php_uri_parser_rfc3986_uris php_uri_parser_rfc3986_uris; +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_uri_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval); + zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_parser_rfc3986_uris *uri, php_uri_component_read_mode read_mode, zval *retval); zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, zval *value, zval *errors); diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c index d140357c18ed..4ca7073847e8 100644 --- a/ext/uri/uri_parser_whatwg.c +++ b/ext/uri/uri_parser_whatwg.c @@ -273,6 +273,11 @@ static zend_result php_uri_parser_whatwg_scheme_write(void *uri, zval *value, zv return SUCCESS; } +ZEND_ATTRIBUTE_NONNULL bool php_uri_parser_whatwg_is_special(const lxb_url_t *lexbor_uri) +{ + return lxb_url_is_special(lexbor_uri); +} + /* 4.2. URL miscellaneous: A URL includes credentials if its username or password is not the empty string. */ static bool includes_credentials(const lxb_url_t *lexbor_uri) { diff --git a/ext/uri/uri_parser_whatwg.h b/ext/uri/uri_parser_whatwg.h index 3e9e2824e42b..1ed2b4ac0e14 100644 --- a/ext/uri/uri_parser_whatwg.h +++ b/ext/uri/uri_parser_whatwg.h @@ -20,6 +20,8 @@ PHPAPI extern const php_uri_parser php_uri_parser_whatwg; +ZEND_ATTRIBUTE_NONNULL bool php_uri_parser_whatwg_is_special(const lxb_url_t *lexbor_uri); + lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, bool silent); PHP_RINIT_FUNCTION(uri_parser_whatwg); From d8a5aec1cc93e0fd41e8641091c32aace2a73059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sun, 24 May 2026 23:54:03 +0200 Subject: [PATCH 5/5] Implement "Followup improvements for ext/uri" RFC - Host type detection (#22100) RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection --- NEWS | 2 + UPGRADING | 2 + ext/uri/php_uri.c | 24 ++++++++++ ext/uri/php_uri.stub.php | 21 +++++++++ ext/uri/php_uri_arginfo.h | 44 ++++++++++++++++++- ext/uri/php_uri_common.h | 2 + ext/uri/php_uri_decl.h | 23 ++++++++-- .../getters/host_type_success_ip_future.phpt | 12 +++++ .../getters/host_type_success_ipv4.phpt | 12 +++++ .../getters/host_type_success_ipv6.phpt | 12 +++++ .../getters/host_type_success_none.phpt | 12 +++++ .../host_type_success_registered_name.phpt | 12 +++++ .../getters/host_type_success_domain.phpt | 12 +++++ .../getters/host_type_success_empty.phpt | 12 +++++ .../getters/host_type_success_ipv4.phpt | 12 +++++ .../getters/host_type_success_ipv6.phpt | 12 +++++ .../getters/host_type_success_none.phpt | 12 +++++ .../getters/host_type_success_opaque.phpt | 12 +++++ ext/uri/uri_parser_rfc3986.c | 24 ++++++++++ ext/uri/uri_parser_rfc3986.h | 1 + ext/uri/uri_parser_whatwg.c | 25 +++++++++++ ext/uri/uri_parser_whatwg.h | 1 + 22 files changed, 296 insertions(+), 5 deletions(-) create mode 100644 ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt create mode 100644 ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt create mode 100644 ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt create mode 100644 ext/uri/tests/rfc3986/getters/host_type_success_none.phpt create mode 100644 ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_domain.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_empty.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_none.phpt create mode 100644 ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt diff --git a/NEWS b/NEWS index bb873c2619da..474698303b53 100644 --- a/NEWS +++ b/NEWS @@ -244,6 +244,8 @@ PHP NEWS - URI: . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). (kocsismate) + . Added Uri\Rfc3986\Uri:getHostType() and Uri\WhatWg\Url:getHostType(). + (kocsismate) - Zip: . Fixed ZipArchive callback being called after executor has shut down. diff --git a/UPGRADING b/UPGRADING index 38858a27ea9d..d9bf1fc79ac1 100644 --- a/UPGRADING +++ b/UPGRADING @@ -214,6 +214,8 @@ PHP 8.6 UPGRADE NOTES - URI: . Added Uri\Rfc3986\Uri:getUriType() and Uri\WhatWg\Url:isSpecialScheme(). RFC: https://wiki.php.net/rfc/uri_followup#uri_type_detection + . Added Uri\Rfc3986\Uri:getHostType() and Uri\WhatWg\Url:getHostType(). + RFC: https://wiki.php.net/rfc/uri_followup#host_type_detection ======================================== 3. Changes in SAPI modules diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 007517ae04d9..58f34a370151 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -32,11 +32,13 @@ zend_class_entry *php_uri_ce_rfc3986_uri; zend_class_entry *php_uri_ce_rfc3986_uri_type; +zend_class_entry *php_uri_ce_rfc3986_uri_host_type; zend_class_entry *php_uri_ce_whatwg_url; zend_class_entry *php_uri_ce_comparison_mode; zend_class_entry *php_uri_ce_exception; zend_class_entry *php_uri_ce_error; zend_class_entry *php_uri_ce_invalid_uri_exception; +zend_class_entry *php_uri_ce_whatwg_url_host_type; zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; zend_class_entry *php_uri_ce_whatwg_url_validation_error; @@ -622,6 +624,16 @@ PHP_METHOD(Uri_Rfc3986_Uri, getRawHost) php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_RAW); } +PHP_METHOD(Uri_Rfc3986_Uri, getHostType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_rfc3986_host_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_Rfc3986_Uri, withHost) { php_uri_property_write_str_or_null_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST); @@ -924,6 +936,16 @@ PHP_METHOD(Uri_WhatWg_Url, getUnicodeHost) php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_HOST, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); } +PHP_METHOD(Uri_WhatWg_Url, getHostType) +{ + ZEND_PARSE_PARAMETERS_NONE(); + + php_uri_object *uri_object = Z_URI_OBJECT_P(ZEND_THIS); + ZEND_ASSERT(uri_object->uri != NULL); + + php_uri_parser_whatwg_host_type_read(uri_object->uri, return_value); +} + PHP_METHOD(Uri_WhatWg_Url, getFragment) { php_uri_property_read_helper(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_URI_PROPERTY_NAME_FRAGMENT, PHP_URI_COMPONENT_READ_MODE_NORMALIZED_UNICODE); @@ -1100,6 +1122,7 @@ static PHP_MINIT_FUNCTION(uri) object_handlers_rfc3986_uri.clone_obj = php_uri_object_handler_clone; php_uri_ce_rfc3986_uri_type = register_class_Uri_Rfc3986_UriType(); + php_uri_ce_rfc3986_uri_host_type = register_class_Uri_Rfc3986_UriHostType(); php_uri_ce_whatwg_url = register_class_Uri_WhatWg_Url(); php_uri_ce_whatwg_url->create_object = php_uri_object_create_whatwg; @@ -1114,6 +1137,7 @@ static PHP_MINIT_FUNCTION(uri) php_uri_ce_error = register_class_Uri_UriError(zend_ce_error); php_uri_ce_invalid_uri_exception = register_class_Uri_InvalidUriException(php_uri_ce_exception); php_uri_ce_whatwg_invalid_url_exception = register_class_Uri_WhatWg_InvalidUrlException(php_uri_ce_invalid_uri_exception); + php_uri_ce_whatwg_url_host_type = register_class_Uri_WhatWg_UrlHostType(); php_uri_ce_whatwg_url_validation_error = register_class_Uri_WhatWg_UrlValidationError(); php_uri_ce_whatwg_url_validation_error_type = register_class_Uri_WhatWg_UrlValidationErrorType(); diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index 03e8a483b0b3..b0b83fcf83ec 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -37,6 +37,14 @@ enum UriType case Uri; } + enum UriHostType + { + case IPv4; + case IPv6; + case IPvFuture; + case RegisteredName; + } + /** @strict-properties */ final readonly class Uri { @@ -70,6 +78,8 @@ public function getHost(): ?string {} public function getRawHost(): ?string {} + public function getHostType(): ?\Uri\Rfc3986\UriHostType {} + public function withHost(?string $host): static {} public function getPort(): ?int {} @@ -162,6 +172,15 @@ enum UrlValidationErrorType public function __construct(string $context, \Uri\WhatWg\UrlValidationErrorType $type, bool $failure) {} } + enum UrlHostType + { + case IPv4; + case IPv6; + case Domain; + case Opaque; + case Empty; + } + /** @strict-properties */ final readonly class Url { @@ -191,6 +210,8 @@ public function getAsciiHost(): ?string {} public function getUnicodeHost(): ?string {} + public function getHostType(): ?\Uri\WhatWg\UrlHostType {} + /** @implementation-alias Uri\Rfc3986\Uri::withHost */ public function withHost(?string $host): static {} diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index e88d439fa16a..0fb464ee74aa 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 php_uri.stub.php instead. - * Stub hash: 4143e681e589d6e663f3f7d9eb7677cd3395baf2 + * Stub hash: a3b4696ac001d537cc34b818715c7eb382c17c5b * Has decl header: yes */ ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_parse, 0, 1, IS_STATIC, 1) @@ -44,6 +44,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_Uri_Rfc3986_Uri_getRawHost arginfo_class_Uri_Rfc3986_Uri_getScheme +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_getHostType, 0, 0, Uri\\Rfc3986\\\125riHostType, 1) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_Uri_withHost, 0, 1, IS_STATIC, 0) ZEND_ARG_TYPE_INFO(0, host, IS_STRING, 1) ZEND_END_ARG_INFO() @@ -152,6 +155,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_Uri_WhatWg_Url_getUnicodeHost arginfo_class_Uri_Rfc3986_Uri_getScheme +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_class_Uri_WhatWg_Url_getHostType, 0, 0, Uri\\WhatWg\\\125rlHostType, 1) +ZEND_END_ARG_INFO() + #define arginfo_class_Uri_WhatWg_Url_withHost arginfo_class_Uri_Rfc3986_Uri_withHost #define arginfo_class_Uri_WhatWg_Url_getPort arginfo_class_Uri_Rfc3986_Uri_getPort @@ -205,6 +211,7 @@ ZEND_METHOD(Uri_Rfc3986_Uri, getPassword); ZEND_METHOD(Uri_Rfc3986_Uri, getRawPassword); ZEND_METHOD(Uri_Rfc3986_Uri, getHost); ZEND_METHOD(Uri_Rfc3986_Uri, getRawHost); +ZEND_METHOD(Uri_Rfc3986_Uri, getHostType); ZEND_METHOD(Uri_Rfc3986_Uri, withHost); ZEND_METHOD(Uri_Rfc3986_Uri, getPort); ZEND_METHOD(Uri_Rfc3986_Uri, withPort); @@ -235,6 +242,7 @@ ZEND_METHOD(Uri_WhatWg_Url, withUsername); ZEND_METHOD(Uri_WhatWg_Url, withPassword); ZEND_METHOD(Uri_WhatWg_Url, getAsciiHost); ZEND_METHOD(Uri_WhatWg_Url, getUnicodeHost); +ZEND_METHOD(Uri_WhatWg_Url, getHostType); ZEND_METHOD(Uri_WhatWg_Url, equals); ZEND_METHOD(Uri_WhatWg_Url, toAsciiString); ZEND_METHOD(Uri_WhatWg_Url, toUnicodeString); @@ -259,6 +267,7 @@ static const zend_function_entry class_Uri_Rfc3986_Uri_methods[] = { ZEND_ME(Uri_Rfc3986_Uri, getRawPassword, arginfo_class_Uri_Rfc3986_Uri_getRawPassword, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getHost, arginfo_class_Uri_Rfc3986_Uri_getHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getRawHost, arginfo_class_Uri_Rfc3986_Uri_getRawHost, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_Rfc3986_Uri, getHostType, arginfo_class_Uri_Rfc3986_Uri_getHostType, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, withHost, arginfo_class_Uri_Rfc3986_Uri_withHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, getPort, arginfo_class_Uri_Rfc3986_Uri_getPort, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_Uri, withPort, arginfo_class_Uri_Rfc3986_Uri_withPort, ZEND_ACC_PUBLIC) @@ -303,6 +312,7 @@ static const zend_function_entry class_Uri_WhatWg_Url_methods[] = { ZEND_ME(Uri_WhatWg_Url, withPassword, arginfo_class_Uri_WhatWg_Url_withPassword, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getAsciiHost, arginfo_class_Uri_WhatWg_Url_getAsciiHost, ZEND_ACC_PUBLIC) ZEND_ME(Uri_WhatWg_Url, getUnicodeHost, arginfo_class_Uri_WhatWg_Url_getUnicodeHost, ZEND_ACC_PUBLIC) + ZEND_ME(Uri_WhatWg_Url, getHostType, arginfo_class_Uri_WhatWg_Url_getHostType, ZEND_ACC_PUBLIC) ZEND_RAW_FENTRY("withHost", zim_Uri_Rfc3986_Uri_withHost, arginfo_class_Uri_WhatWg_Url_withHost, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("getPort", zim_Uri_Rfc3986_Uri_getPort, arginfo_class_Uri_WhatWg_Url_getPort, ZEND_ACC_PUBLIC, NULL, NULL) ZEND_RAW_FENTRY("withPort", zim_Uri_Rfc3986_Uri_withPort, arginfo_class_Uri_WhatWg_Url_withPort, ZEND_ACC_PUBLIC, NULL, NULL) @@ -378,6 +388,21 @@ static zend_class_entry *register_class_Uri_Rfc3986_UriType(void) return class_entry; } +static zend_class_entry *register_class_Uri_Rfc3986_UriHostType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\Rfc3986\\UriHostType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "IPv4", NULL); + + zend_enum_add_case_cstr(class_entry, "IPv6", NULL); + + zend_enum_add_case_cstr(class_entry, "IPvFuture", NULL); + + zend_enum_add_case_cstr(class_entry, "RegisteredName", NULL); + + return class_entry; +} + static zend_class_entry *register_class_Uri_Rfc3986_Uri(void) { zend_class_entry ce, *class_entry; @@ -499,6 +524,23 @@ static zend_class_entry *register_class_Uri_WhatWg_UrlValidationError(void) return class_entry; } +static zend_class_entry *register_class_Uri_WhatWg_UrlHostType(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\WhatWg\\UrlHostType", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "IPv4", NULL); + + zend_enum_add_case_cstr(class_entry, "IPv6", NULL); + + zend_enum_add_case_cstr(class_entry, "Domain", NULL); + + zend_enum_add_case_cstr(class_entry, "Opaque", NULL); + + zend_enum_add_case_cstr(class_entry, "Empty", NULL); + + return class_entry; +} + static zend_class_entry *register_class_Uri_WhatWg_Url(void) { zend_class_entry ce, *class_entry; diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 4c0ac466da78..c9f5e81075fe 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -19,6 +19,7 @@ extern zend_class_entry *php_uri_ce_rfc3986_uri; extern zend_class_entry *php_uri_ce_rfc3986_uri_type; +extern zend_class_entry *php_uri_ce_rfc3986_uri_host_type; extern zend_class_entry *php_uri_ce_whatwg_url; extern zend_class_entry *php_uri_ce_comparison_mode; extern zend_class_entry *php_uri_ce_exception; @@ -27,6 +28,7 @@ extern zend_class_entry *php_uri_ce_invalid_uri_exception; extern zend_class_entry *php_uri_ce_whatwg_invalid_url_exception; extern zend_class_entry *php_uri_ce_whatwg_url_validation_error_type; extern zend_class_entry *php_uri_ce_whatwg_url_validation_error; +extern zend_class_entry *php_uri_ce_whatwg_url_host_type; typedef enum php_uri_recomposition_mode { PHP_URI_RECOMPOSITION_MODE_RAW_ASCII, diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h index 947858515dbb..d1fd58d04b2c 100644 --- a/ext/uri/php_uri_decl.h +++ b/ext/uri/php_uri_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: 4143e681e589d6e663f3f7d9eb7677cd3395baf2 */ + * Stub hash: a3b4696ac001d537cc34b818715c7eb382c17c5b */ -#ifndef ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H -#define ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H +#ifndef ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H +#define ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H typedef enum zend_enum_Uri_UriComparisonMode { ZEND_ENUM_Uri_UriComparisonMode_IncludeFragment = 1, @@ -16,6 +16,13 @@ typedef enum zend_enum_Uri_Rfc3986_UriType { ZEND_ENUM_Uri_Rfc3986_UriType_Uri = 4, } zend_enum_Uri_Rfc3986_UriType; +typedef enum zend_enum_Uri_Rfc3986_UriHostType { + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv4 = 1, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPv6 = 2, + ZEND_ENUM_Uri_Rfc3986_UriHostType_IPvFuture = 3, + ZEND_ENUM_Uri_Rfc3986_UriHostType_RegisteredName = 4, +} zend_enum_Uri_Rfc3986_UriHostType; + typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToAscii = 1, ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_DomainToUnicode = 2, @@ -48,4 +55,12 @@ typedef enum zend_enum_Uri_WhatWg_UrlValidationErrorType { ZEND_ENUM_Uri_WhatWg_UrlValidationErrorType_FileInvalidWindowsDriveLetterHost = 29, } zend_enum_Uri_WhatWg_UrlValidationErrorType; -#endif /* ZEND_PHP_URI_DECL_4143e681e589d6e663f3f7d9eb7677cd3395baf2_H */ +typedef enum zend_enum_Uri_WhatWg_UrlHostType { + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv4 = 1, + ZEND_ENUM_Uri_WhatWg_UrlHostType_IPv6 = 2, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Domain = 3, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Opaque = 4, + ZEND_ENUM_Uri_WhatWg_UrlHostType_Empty = 5, +} zend_enum_Uri_WhatWg_UrlHostType; + +#endif /* ZEND_PHP_URI_DECL_a3b4696ac001d537cc34b818715c7eb382c17c5b_H */ diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt new file mode 100644 index 000000000000..0ac7ea3f7efd --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ip_future.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IP future +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPvFuture) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt new file mode 100644 index 000000000000..1c0c4448b953 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ipv4.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IPv4 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPv4) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt new file mode 100644 index 000000000000..5f3d826b412a --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_ipv6.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - IPv6 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::IPv6) diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt new file mode 100644 index 000000000000..3a0e0205befe --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_none.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - none +--FILE-- +getHostType()); + +?> +--EXPECT-- +NULL diff --git a/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt b/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt new file mode 100644 index 000000000000..31d4aca36c82 --- /dev/null +++ b/ext/uri/tests/rfc3986/getters/host_type_success_registered_name.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\Rfc3986\Uri component retrieval - host type - registered name +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\Rfc3986\UriHostType::RegisteredName) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_domain.phpt b/ext/uri/tests/whatwg/getters/host_type_success_domain.phpt new file mode 100644 index 000000000000..21fc961e5541 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_domain.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - registered name +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Domain) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt b/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt new file mode 100644 index 000000000000..41351350fb61 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_empty.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - empty +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Empty) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt b/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt new file mode 100644 index 000000000000..f2f63caabb5e --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_ipv4.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - IPv4 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::IPv4) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt b/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt new file mode 100644 index 000000000000..ce5bb00b93d5 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_ipv6.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - IPv6 +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::IPv6) diff --git a/ext/uri/tests/whatwg/getters/host_type_success_none.phpt b/ext/uri/tests/whatwg/getters/host_type_success_none.phpt new file mode 100644 index 000000000000..07d54412a23c --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_none.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - none +--FILE-- +getHostType()); + +?> +--EXPECT-- +NULL diff --git a/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt b/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt new file mode 100644 index 000000000000..844cba82d512 --- /dev/null +++ b/ext/uri/tests/whatwg/getters/host_type_success_opaque.phpt @@ -0,0 +1,12 @@ +--TEST-- +Test Uri\WhatWg\Url component retrieval - host type - opaque +--FILE-- +getHostType()); + +?> +--EXPECT-- +enum(Uri\WhatWg\UrlHostType::Opaque) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index cdf88013252f..ad47aa1946c7 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -271,6 +271,30 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void return SUCCESS; } +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_host_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval) +{ + const UriUriA *uriparser_uri = get_uri_for_reading(uri, PHP_URI_COMPONENT_READ_MODE_RAW); + + if (!has_text_range(&uriparser_uri->hostText)) { + ZVAL_NULL(retval); + return; + } + + const char *type; + + if (uriparser_uri->hostData.ip4 != NULL) { + type = "IPv4"; + } else if (uriparser_uri->hostData.ip6 != NULL) { + type = "IPv6"; + } else if (has_text_range(&uriparser_uri->hostData.ipFuture)) { + type = "IPvFuture"; + } else { + type = "RegisteredName"; + } + + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_rfc3986_uri_host_type, type)); +} + static zend_result php_uri_parser_rfc3986_host_write(void *uri, zval *value, zval *errors) { UriUriA *uriparser_uri = get_uri_for_writing(uri); diff --git a/ext/uri/uri_parser_rfc3986.h b/ext/uri/uri_parser_rfc3986.h index bf8a0733fc8a..633dd72062f2 100644 --- a/ext/uri/uri_parser_rfc3986.h +++ b/ext/uri/uri_parser_rfc3986.h @@ -22,6 +22,7 @@ PHPAPI extern const php_uri_parser php_uri_parser_rfc3986; typedef struct php_uri_parser_rfc3986_uris php_uri_parser_rfc3986_uris; ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_uri_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval); +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_rfc3986_host_type_read(php_uri_parser_rfc3986_uris *uri, zval *retval); zend_result php_uri_parser_rfc3986_userinfo_read(php_uri_parser_rfc3986_uris *uri, php_uri_component_read_mode read_mode, zval *retval); zend_result php_uri_parser_rfc3986_userinfo_write(php_uri_parser_rfc3986_uris *uri, zval *value, zval *errors); diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c index 4ca7073847e8..f4e148704004 100644 --- a/ext/uri/uri_parser_whatwg.c +++ b/ext/uri/uri_parser_whatwg.c @@ -386,6 +386,31 @@ static zend_result php_uri_parser_whatwg_host_read(void *uri, php_uri_component_ return SUCCESS; } +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_whatwg_host_type_read(const lxb_url_t *lexbor_uri, zval *retval) +{ + switch (lexbor_uri->host.type) { + case LXB_URL_HOST_TYPE_IPV4: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "IPv4")); + return; + case LXB_URL_HOST_TYPE_IPV6: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "IPv6")); + return; + case LXB_URL_HOST_TYPE_DOMAIN: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Domain")); + return; + case LXB_URL_HOST_TYPE_EMPTY: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Empty")); + return; + case LXB_URL_HOST_TYPE_OPAQUE: + ZVAL_OBJ_COPY(retval, zend_enum_get_case_cstr(php_uri_ce_whatwg_url_host_type, "Opaque")); + return; + case LXB_URL_HOST_TYPE__UNDEF: + ZVAL_NULL(retval); + return; + default: ZEND_UNREACHABLE(); + } +} + static zend_result php_uri_parser_whatwg_host_write(void *uri, zval *value, zval *errors) { lxb_url_t *lexbor_uri = uri; diff --git a/ext/uri/uri_parser_whatwg.h b/ext/uri/uri_parser_whatwg.h index 1ed2b4ac0e14..f714ee483680 100644 --- a/ext/uri/uri_parser_whatwg.h +++ b/ext/uri/uri_parser_whatwg.h @@ -21,6 +21,7 @@ PHPAPI extern const php_uri_parser php_uri_parser_whatwg; ZEND_ATTRIBUTE_NONNULL bool php_uri_parser_whatwg_is_special(const lxb_url_t *lexbor_uri); +ZEND_ATTRIBUTE_NONNULL void php_uri_parser_whatwg_host_type_read(const lxb_url_t *lexbor_uri, zval *retval); lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, bool silent);