Skip to content

Commit 0fab842

Browse files
committed
Add UriComparisonMode
1 parent 88c8a46 commit 0fab842

File tree

6 files changed

+61
-69
lines changed

6 files changed

+61
-69
lines changed

ext/uri/php_uri.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ zend_class_entry *rfc3986_uri_ce;
3434
zend_object_handlers rfc3986_uri_object_handlers;
3535
zend_class_entry *whatwg_url_ce;
3636
zend_object_handlers whatwg_uri_object_handlers;
37+
zend_class_entry *uri_comparison_mode_ce;
3738
zend_class_entry *uri_exception_ce;
3839
zend_class_entry *invalid_uri_exception_ce;
3940
zend_class_entry *whatwg_invalid_url_exception_ce;
@@ -397,16 +398,6 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
397398
Z_PARAM_PATH_STR_OR_NULL(base_url_str)
398399
ZEND_PARSE_PARAMETERS_END();
399400

400-
if (ZSTR_LEN(uri_str) == 0) {
401-
zend_argument_value_error(1, "cannot be empty");
402-
RETURN_THROWS();
403-
}
404-
405-
if (base_url_str && ZSTR_LEN(base_url_str) == 0) {
406-
zend_argument_value_error(2, "cannot be empty");
407-
RETURN_THROWS();
408-
}
409-
410401
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &uriparser_uri_handler, uri_str, base_url_str, is_constructor, NULL);
411402
}
412403

@@ -432,16 +423,6 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
432423
Z_PARAM_ZVAL(errors)
433424
ZEND_PARSE_PARAMETERS_END();
434425

435-
if (ZSTR_LEN(uri_str) == 0) {
436-
zend_argument_value_error(1, "cannot be empty");
437-
RETURN_THROWS();
438-
}
439-
440-
if (base_url_str && ZSTR_LEN(base_url_str) == 0) {
441-
zend_argument_value_error(2, "cannot be empty");
442-
RETURN_THROWS();
443-
}
444-
445426
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &lexbor_uri_handler, uri_str, base_url_str, is_constructor, errors);
446427
}
447428

@@ -575,7 +556,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, withFragment)
575556
URI_WITHER_STR_OR_NULL(ZSTR_KNOWN(ZEND_STR_FRAGMENT));
576557
}
577558

578-
static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, bool exclude_fragment)
559+
static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, zend_object *comparison_mode)
579560
{
580561
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
581562
uri_internal_t *this_internal_uri = uri_internal_from_obj(this_object);
@@ -591,6 +572,14 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, b
591572
RETURN_FALSE;
592573
}
593574

575+
bool exclude_fragment = true;
576+
if (comparison_mode) {
577+
zval *case_name = zend_enum_fetch_case_name(comparison_mode);
578+
zend_string *comparison_mode_name = Z_STR_P(case_name);
579+
580+
exclude_fragment = ZSTR_VAL(comparison_mode_name)[0] + ZSTR_LEN(comparison_mode_name) == 'E' + sizeof("ExcludeFragment") - 1;
581+
}
582+
594583
zend_string *this_str = this_internal_uri->handler->uri_to_string(
595584
this_internal_uri->uri, URI_RECOMPOSITION_NORMALIZED_ASCII, exclude_fragment);
596585
if (this_str == NULL) {
@@ -614,15 +603,15 @@ static void uri_equals(INTERNAL_FUNCTION_PARAMETERS, zend_object *that_object, b
614603
PHP_METHOD(Uri_Rfc3986_Uri, equals)
615604
{
616605
zend_object *that_object;
617-
bool exclude_fragment = true;
606+
zend_object *comparison_mode = NULL;
618607

619608
ZEND_PARSE_PARAMETERS_START(1, 2)
620609
Z_PARAM_OBJ_OF_CLASS(that_object, rfc3986_uri_ce)
621610
Z_PARAM_OPTIONAL
622-
Z_PARAM_BOOL(exclude_fragment)
611+
Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce);
623612
ZEND_PARSE_PARAMETERS_END();
624613

625-
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, exclude_fragment);
614+
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, comparison_mode);
626615
}
627616

628617
PHP_METHOD(Uri_Rfc3986_Uri, toRawString)
@@ -832,15 +821,15 @@ PHP_METHOD(Uri_WhatWg_Url, withHost)
832821
PHP_METHOD(Uri_WhatWg_Url, equals)
833822
{
834823
zend_object *that_object;
835-
bool exclude_fragment = true;
824+
zend_object *comparison_mode = NULL;
836825

837826
ZEND_PARSE_PARAMETERS_START(1, 2)
838827
Z_PARAM_OBJ_OF_CLASS(that_object, whatwg_url_ce)
839828
Z_PARAM_OPTIONAL
840-
Z_PARAM_BOOL(exclude_fragment)
829+
Z_PARAM_OBJ_OF_CLASS(comparison_mode, uri_comparison_mode_ce);
841830
ZEND_PARSE_PARAMETERS_END();
842831

843-
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, exclude_fragment);
832+
uri_equals(INTERNAL_FUNCTION_PARAM_PASSTHRU, that_object, comparison_mode);
844833
}
845834

846835
PHP_METHOD(Uri_WhatWg_Url, toUnicodeString)
@@ -955,6 +944,7 @@ static PHP_MINIT_FUNCTION(uri)
955944
whatwg_url_ce = register_class_Uri_WhatWg_Url();
956945
php_uri_implementation_set_object_handlers(whatwg_url_ce, &whatwg_uri_object_handlers);
957946

947+
uri_comparison_mode_ce = register_class_Uri_UriComparisonMode();
958948
uri_exception_ce = register_class_Uri_UriException(zend_ce_exception);
959949
invalid_uri_exception_ce = register_class_Uri_InvalidUriException(uri_exception_ce);
960950
whatwg_invalid_url_exception_ce = register_class_Uri_WhatWg_InvalidUrlException(invalid_uri_exception_ce);

ext/uri/php_uri.stub.php

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ class UriException extends \Exception
1212
class InvalidUriException extends \Uri\UriException
1313
{
1414
}
15+
16+
enum UriComparisonMode
17+
{
18+
case IncludeFragment;
19+
case ExcludeFragment;
20+
}
1521
}
1622

1723
namespace Uri\Rfc3986 {
@@ -70,7 +76,7 @@ public function getRawFragment(): ?string {}
7076

7177
public function withFragment(?string $fragment): static {}
7278

73-
public function equals(\Uri\Rfc3986\Uri $uri, bool $excludeFragment = true): bool {}
79+
public function equals(\Uri\Rfc3986\Uri $uri, \Uri\UriComparisonMode $comparisonMode = \Uri\UriComparisonMode::ExcludeFragment): bool {}
7480

7581
public function toString(): string {}
7682

@@ -189,7 +195,7 @@ public function getFragment(): ?string {}
189195
/** @implementation-alias Uri\Rfc3986\Uri::withFragment */
190196
public function withFragment(?string $fragment): static {}
191197

192-
public function equals(\Uri\WhatWg\Url $url, bool $excludeFragment = true): bool {}
198+
public function equals(\Uri\WhatWg\Url $url, \Uri\UriComparisonMode $comparisonMode = \Uri\UriComparisonMode::ExcludeFragment): bool {}
193199

194200
public function toAsciiString(): string {}
195201

ext/uri/php_uri_arginfo.h

Lines changed: 14 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/uri/php_uri_common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ extern zend_class_entry *rfc3986_uri_ce;
2121
extern zend_object_handlers rfc3986_uri_object_handlers;
2222
extern zend_class_entry *whatwg_url_ce;
2323
extern zend_object_handlers whatwg_uri_object_handlers;
24+
extern zend_class_entry *uri_comparison_mode_ce;
2425
extern zend_class_entry *uri_exception_ce;
2526
extern zend_class_entry *invalid_uri_exception_ce;
2627
extern zend_class_entry *whatwg_invalid_url_exception_ce;

ext/uri/tests/004.phpt

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -7,51 +7,35 @@ uri
77

88
try {
99
new Uri\Rfc3986\Uri("");
10-
} catch (ValueError $e) {
10+
} catch (Uri\InvalidUriException $e) {
1111
echo $e->getMessage() . "\n";
1212
}
1313

14-
try {
15-
Uri\Rfc3986\Uri::parse("");
16-
} catch (ValueError $e) {
17-
echo $e->getMessage() . "\n";
18-
}
14+
var_dump(Uri\Rfc3986\Uri::parse(""));
1915

2016
try {
2117
new Uri\WhatWg\Url("");
22-
} catch (ValueError $e) {
18+
} catch (Uri\WhatWg\InvalidUrlException $e) {
2319
echo $e->getMessage() . "\n";
2420
}
2521

26-
try {
27-
Uri\WhatWg\Url::parse("");
28-
} catch (ValueError $e) {
29-
echo $e->getMessage() . "\n";
30-
}
31-
32-
try {
33-
Uri\Rfc3986\Uri::parse("https://example.com", "");
34-
} catch (ValueError $e) {
35-
echo $e->getMessage() . "\n";
36-
}
22+
var_dump(Uri\WhatWg\Url::parse(""));
3723

3824
try {
3925
new Uri\Rfc3986\Uri("https://example.com", "");
40-
} catch (ValueError $e) {
26+
} catch (Uri\InvalidUriException $e) {
4127
echo $e->getMessage() . "\n";
4228
}
4329

30+
var_dump(Uri\Rfc3986\Uri::parse("https://example.com", ""));
31+
4432
try {
4533
new Uri\WhatWg\Url("https://example.com", "");
46-
} catch (ValueError $e) {
34+
} catch (Uri\WhatWg\InvalidUrlException $e) {
4735
echo $e->getMessage() . "\n";
4836
}
4937

50-
try {
51-
Uri\WhatWg\Url::parse("https://example.com", "");
52-
} catch (ValueError $e) {
53-
echo $e->getMessage() . "\n";
54-
}
38+
var_dump(Uri\WhatWg\Url::parse("https://example.com", ""));
5539

5640
var_dump(Uri\Rfc3986\Uri::parse("192.168/contact.html"));
5741
var_dump(Uri\WhatWg\Url::parse("192.168/contact.html", null));
@@ -61,14 +45,14 @@ var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Ca
6145

6246
?>
6347
--EXPECTF--
64-
Uri\Rfc3986\Uri::__construct(): Argument #1 ($uri) cannot be empty
65-
Uri\Rfc3986\Uri::parse(): Argument #1 ($uri) cannot be empty
66-
Uri\WhatWg\Url::__construct(): Argument #1 ($uri) cannot be empty
67-
Uri\WhatWg\Url::parse(): Argument #1 ($uri) cannot be empty
68-
Uri\Rfc3986\Uri::parse(): Argument #2 ($baseUrl) cannot be empty
69-
Uri\Rfc3986\Uri::__construct(): Argument #2 ($baseUrl) cannot be empty
70-
Uri\WhatWg\Url::__construct(): Argument #2 ($baseUrl) cannot be empty
71-
Uri\WhatWg\Url::parse(): Argument #2 ($baseUrl) cannot be empty
48+
URI parsing failed
49+
NULL
50+
URL parsing failed
51+
NULL
52+
URI parsing failed
53+
NULL
54+
URL parsing failed
55+
NULL
7256
object(Uri\Rfc3986\Uri)#%d (%d) {
7357
["scheme"]=>
7458
NULL

ext/uri/tests/036.phpt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,16 @@ uri
66
<?php
77

88
var_dump(new Uri\Rfc3986\Uri("https://example.com")->equals(new Uri\Rfc3986\Uri("https://example.com"))); // true: identical URIs
9-
var_dump(new Uri\Rfc3986\Uri("https://example.com#foo")->equals(new Uri\Rfc3986\Uri("https://example.com#bar"), true)); // true: fragment differs, but excludeFragment = true
10-
var_dump(new Uri\Rfc3986\Uri("https://example.com#foo")->equals(new Uri\Rfc3986\Uri("https://example.com#bar"), false)); // false: fragment differs and excludeFragment = false
9+
var_dump(new Uri\Rfc3986\Uri("https://example.com#foo")->equals(new Uri\Rfc3986\Uri("https://example.com#bar"), Uri\UriComparisonMode::ExcludeFragment)); // true: fragment differs, but fragment is excluded
10+
var_dump(new Uri\Rfc3986\Uri("https://example.com#foo")->equals(new Uri\Rfc3986\Uri("https://example.com#bar"), Uri\UriComparisonMode::IncludeFragment)); // false: fragment differs and fragment is included
1111
var_dump(new Uri\Rfc3986\Uri("https://example.com/foo/..")->equals(new Uri\Rfc3986\Uri("https://example.com"))); // false: first URI becomes https://example.com/ after normalization
1212
var_dump(new Uri\Rfc3986\Uri("https://example.com/foo/..")->equals(new Uri\Rfc3986\Uri("https://example.com/"))); // true: both URIs are https://example.com/ after normalization
1313
var_dump(new Uri\Rfc3986\Uri("http://example%2ecom/foo%2fb%61r")->equals(new Uri\Rfc3986\Uri("http://example%2ecom/foo/bar"))); // false: "/" in the path should not be decoded
1414
var_dump(new Uri\Rfc3986\Uri("http://example%2ecom/foo/b%61r")->equals(new Uri\Rfc3986\Uri("http://example%2ecom/foo/bar"))); // true: percent-decoding during normalization gives same URIs
1515

1616
var_dump(new Uri\WhatWg\Url("https://example.com")->equals(new Uri\WhatWg\Url("https://example.com"))); // true: identical URIs
17-
var_dump(new Uri\WhatWg\Url("https://example.com#foo")->equals(new Uri\WhatWg\Url("https://example.com#bar"), true)); // true: fragment differs, but excludeFragment = true
18-
var_dump(new Uri\WhatWg\Url("https://example.com#foo")->equals(new Uri\WhatWg\Url("https://example.com#bar"), false)); // false: fragment differs and excludeFragment = false
17+
var_dump(new Uri\WhatWg\Url("https://example.com#foo")->equals(new Uri\WhatWg\Url("https://example.com#bar"), Uri\UriComparisonMode::ExcludeFragment)); // true: fragment differs, but fragment is excluded
18+
var_dump(new Uri\WhatWg\Url("https://example.com#foo")->equals(new Uri\WhatWg\Url("https://example.com#bar"), Uri\UriComparisonMode::IncludeFragment)); // false: fragment differs and fragment is included
1919
var_dump(new Uri\WhatWg\Url("https://example.com/foo/..")->equals(new Uri\WhatWg\Url("https://example.com"))); // true: both URIs are https://example.com/ after normalization
2020
var_dump(new Uri\WhatWg\Url("https://example.com/foo/..")->equals(new Uri\WhatWg\Url("https://example.com/"))); // true: both URIs are https://example.com/ after normalization
2121
var_dump(new Uri\WhatWg\Url("http://example%2ecom/foo%2fb%61r")->equals(new Uri\WhatWg\Url("http://example%2ecom/foo/bar"))); // false: WHATWG doesn't percent-decode the path during normalization

0 commit comments

Comments
 (0)