Skip to content

Commit 6dddb92

Browse files
committed
uri: Reject out-of-range ports for uri_parser_rfc3986
RFC 3986 technically allows arbitrarily large integers as port numbers, but our implementation is unable to deal with that, since it expects the port to fit `zend_long`. In practice these port numbers are unusable, so we might as well reject them.
1 parent 243aedd commit 6dddb92

File tree

3 files changed

+35
-3
lines changed

3 files changed

+35
-3
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ PHP NEWS
2525
(timwolla)
2626
. Fixed double-free when assigning to $errors fails when using
2727
the Uri\WhatWg\Url parser. (timwolla)
28+
. Reject out-of-range ports when using the Uri\Rfc3986\Uri parser.
29+
(timwolla)
2830
. Clean up naming of internal API. (timwolla)
2931

3032
28 Aug 2025, PHP 8.5.0beta2

ext/uri/tests/058.phpt

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
--TEST--
2+
Test that out of range ports are rejected
3+
--EXTENSIONS--
4+
uri
5+
--FILE--
6+
<?php
7+
8+
try {
9+
new \Uri\Rfc3986\Uri('https://example.com:987654321987654321987654321987654321');
10+
} catch (Throwable $e) {
11+
echo $e::class, ": ", $e->getMessage(), PHP_EOL;
12+
}
13+
14+
?>
15+
--EXPECT--
16+
Uri\InvalidUriException: The port is out of range

ext/uri/uri_parser_rfc3986.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -190,11 +190,11 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(const
190190
return SUCCESS;
191191
}
192192

193-
ZEND_ATTRIBUTE_NONNULL static size_t str_to_int(const char *str, size_t len)
193+
ZEND_ATTRIBUTE_NONNULL static zend_ulong str_to_int(const char *str, size_t len)
194194
{
195-
size_t result = 0;
195+
zend_ulong result = 0;
196196

197-
for (size_t i = 0; i < len; ++i) {
197+
for (zend_ulong i = 0; i < len; ++i) {
198198
result = result * 10 + (str[i] - '0');
199199
}
200200

@@ -319,6 +319,20 @@ php_uri_parser_rfc3986_uris *php_uri_parser_rfc3986_parse_ex(const char *uri_str
319319
/* Make the resulting URI independent of the 'uri_str'. */
320320
uriMakeOwnerMmA(&uri, mm);
321321

322+
if (has_text_range(&uri.portText)) {
323+
size_t port_length = get_text_range_length(&uri.portText);
324+
if (
325+
port_length > 5
326+
|| str_to_int(uri.portText.first, port_length) > 65535
327+
) {
328+
if (!silent) {
329+
zend_throw_exception(uri_invalid_uri_exception_ce, "The port is out of range", 0);
330+
}
331+
332+
goto fail;
333+
}
334+
}
335+
322336
php_uri_parser_rfc3986_uris *uriparser_uris = uriparser_create_uris();
323337
uriparser_uris->uri = uri;
324338

0 commit comments

Comments
 (0)