Skip to content

Commit 0a1d1ec

Browse files
committed
Expose $softErrors for Uri\WhatWg\Url::resolve()
1 parent b8a8ba7 commit 0a1d1ec

File tree

7 files changed

+112
-19
lines changed

7 files changed

+112
-19
lines changed

ext/uri/php_uri.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ static zend_result pass_errors_by_ref(zval *errors_zv, zval *errors)
355355

356356
PHPAPI void php_uri_instantiate_uri(
357357
INTERNAL_FUNCTION_PARAMETERS, const uri_handler_t *handler, const zend_string *uri_str, const zend_object *base_url_object,
358-
bool is_constructor, zval *errors_zv
358+
bool should_throw, bool should_update_this_object, zval *errors_zv
359359
) {
360360
zval errors;
361361
ZVAL_UNDEF(&errors);
@@ -367,9 +367,9 @@ PHPAPI void php_uri_instantiate_uri(
367367
base_url = internal_base_url->uri;
368368
}
369369

370-
void *uri = handler->parse_uri(uri_str, base_url, is_constructor || errors_zv != NULL ? &errors : NULL);
370+
void *uri = handler->parse_uri(uri_str, base_url, should_throw || errors_zv != NULL ? &errors : NULL);
371371
if (UNEXPECTED(uri == NULL)) {
372-
if (is_constructor) {
372+
if (should_throw) {
373373
throw_invalid_uri_exception(handler, &errors);
374374
zval_ptr_dtor(&errors);
375375
RETURN_THROWS();
@@ -384,10 +384,14 @@ PHPAPI void php_uri_instantiate_uri(
384384
zval_ptr_dtor(&errors);
385385

386386
uri_object_t *uri_object;
387-
if (is_constructor) {
387+
if (should_update_this_object) {
388388
uri_object = Z_URI_OBJECT_P(ZEND_THIS);
389389
} else {
390-
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
390+
if (EX(func)->common.fn_flags & ZEND_ACC_STATIC) {
391+
object_init_ex(return_value, Z_CE_P(ZEND_THIS));
392+
} else {
393+
object_init_ex(return_value, Z_OBJCE_P(ZEND_THIS));
394+
}
391395
uri_object = Z_URI_OBJECT_P(return_value);
392396
}
393397

@@ -406,7 +410,7 @@ static void create_rfc3986_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor
406410
Z_PARAM_OBJ_OF_CLASS_OR_NULL(base_url_object, rfc3986_uri_ce)
407411
ZEND_PARSE_PARAMETERS_END();
408412

409-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &uriparser_uri_handler, uri_str, base_url_object, is_constructor, NULL);
413+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &uriparser_uri_handler, uri_str, base_url_object, is_constructor, is_constructor, NULL);
410414
}
411415

412416
PHP_METHOD(Uri_Rfc3986_Uri, parse)
@@ -432,7 +436,7 @@ static void create_whatwg_uri(INTERNAL_FUNCTION_PARAMETERS, bool is_constructor)
432436
Z_PARAM_ZVAL(errors)
433437
ZEND_PARSE_PARAMETERS_END();
434438

435-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &lexbor_uri_handler, uri_str, base_url_object, is_constructor, errors);
439+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, &lexbor_uri_handler, uri_str, base_url_object, is_constructor, is_constructor, errors);
436440
}
437441

438442
PHP_METHOD(Uri_WhatWg_Url, parse)
@@ -669,7 +673,7 @@ PHP_METHOD(Uri_Rfc3986_Uri, resolve)
669673
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
670674
URI_CHECK_INITIALIZATION(internal_uri);
671675

672-
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->handler, uri_str, this_object, true, NULL);
676+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->handler, uri_str, this_object, true, false, NULL);
673677
}
674678

675679
PHP_METHOD(Uri_Rfc3986_Uri, __serialize)
@@ -856,6 +860,24 @@ PHP_METHOD(Uri_WhatWg_Url, toAsciiString)
856860
RETURN_STR(internal_uri->handler->uri_to_string(internal_uri->uri, URI_RECOMPOSITION_RAW_ASCII, false));
857861
}
858862

863+
PHP_METHOD(Uri_WhatWg_Url, resolve)
864+
{
865+
zend_string *uri_str;
866+
zval *errors = NULL;
867+
868+
ZEND_PARSE_PARAMETERS_START(1, 2)
869+
Z_PARAM_PATH_STR(uri_str)
870+
Z_PARAM_OPTIONAL
871+
Z_PARAM_ZVAL(errors)
872+
ZEND_PARSE_PARAMETERS_END();
873+
874+
zend_object *this_object = Z_OBJ_P(ZEND_THIS);
875+
uri_internal_t *internal_uri = uri_internal_from_obj(this_object);
876+
URI_CHECK_INITIALIZATION(internal_uri);
877+
878+
php_uri_instantiate_uri(INTERNAL_FUNCTION_PARAM_PASSTHRU, internal_uri->handler, uri_str, this_object, true, false, errors);
879+
}
880+
859881
PHP_METHOD(Uri_WhatWg_Url, __unserialize)
860882
{
861883
uri_unserialize(INTERNAL_FUNCTION_PARAM_PASSTHRU, URI_PARSER_WHATWG);

ext/uri/php_uri.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ PHPAPI void php_uri_struct_free(php_uri *uri);
5353

5454
PHPAPI void php_uri_instantiate_uri(
5555
INTERNAL_FUNCTION_PARAMETERS, const uri_handler_t *handler, const zend_string *uri_str, const zend_object *base_url_object,
56-
bool is_constructor, zval *errors_zv
56+
bool should_throw, bool should_update_this_object, zval *errors_zv
5757
);
5858
PHPAPI void php_uri_implementation_set_object_handlers(zend_class_entry *ce, zend_object_handlers *object_handlers);
5959

ext/uri/php_uri.stub.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ public function toAsciiString(): string {}
201201

202202
public function toUnicodeString(): string {}
203203

204-
/** @implementation-alias Uri\Rfc3986\Uri::resolve */
205-
public function resolve(string $uri): static {}
204+
/** @param array $softErrors */
205+
public function resolve(string $uri, &$softErrors = null): static {}
206206

207207
/** @implementation-alias Uri\Rfc3986\Uri::__serialize */
208208
public function __serialize(): array {}

ext/uri/php_uri_arginfo.h

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

ext/uri/php_uriparser.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,13 +66,12 @@ static void uriparser_copy_text_range(UriTextRangeA *text_range, UriTextRangeA *
6666
new_text_range->first = uriSafeToPointToA;
6767
new_text_range->afterLast = uriSafeToPointToA;
6868
} else {
69-
size_t char_length = (size_t) (text_range->afterLast - text_range->first);
70-
size_t bytes_length = char_length * sizeof(char);
71-
char *dup = emalloc(bytes_length); // TODO remove if wchar support is not necessary
72-
memcpy(dup, text_range->first, bytes_length);
69+
size_t length = (size_t) (text_range->afterLast - text_range->first);
70+
char *dup = emalloc(length);
71+
memcpy(dup, text_range->first, length);
7372

7473
new_text_range->first = dup;
75-
new_text_range->afterLast = dup + char_length;
74+
new_text_range->afterLast = dup + length;
7675
}
7776
}
7877

@@ -652,6 +651,7 @@ static void *uriparser_parse_uri(const zend_string *uri_str, const void *base_ur
652651
}
653652

654653
efree(uriparser_uri);
654+
efree(uriparser_base_url);
655655

656656
return uriparser_create_uris(absolute_uri, original_uri_str, NULL, NULL);
657657
}

ext/uri/tests/050.phpt

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Test resolve() method - success cases
3+
--EXTENSIONS--
4+
uri
5+
--FILE--
6+
<?php
7+
8+
$uri = new Uri\Rfc3986\Uri("https://example.com");
9+
10+
var_dump($uri->resolve("/foo/")->toString());
11+
var_dump($uri->resolve("https://test.com/foo")->toString());
12+
13+
$url = new Uri\WhatWg\Url("https://example.com");
14+
15+
var_dump($url->resolve("/foo/")->toAsciiString());
16+
var_dump($url->resolve("https://test.com/foo")->toAsciiString());
17+
18+
?>
19+
--EXPECTF--
20+
string(24) "https://example.com/foo/"
21+
string(20) "https://test.com/foo"
22+
string(24) "https://example.com/foo/"
23+
string(20) "https://test.com/foo"

ext/uri/tests/051.phpt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
--TEST--
2+
Test resolve() method - error cases
3+
--EXTENSIONS--
4+
uri
5+
--FILE--
6+
<?php
7+
8+
$uri = new Uri\Rfc3986\Uri("https://example.com");
9+
10+
try {
11+
$uri->resolve("á");
12+
} catch (Uri\InvalidUriException $e) {
13+
echo $e->getMessage() . "\n";
14+
}
15+
16+
$url = new Uri\WhatWg\Url("https://example.com");
17+
18+
try {
19+
$url->resolve("https://1.2.3.4.5");
20+
} catch (Uri\WhatWg\InvalidUrlException $e) {
21+
echo $e->getMessage() . "\n";
22+
}
23+
24+
$softErrors = [];
25+
26+
var_dump($url->resolve(" /foo", $softErrors)->toAsciiString());
27+
var_dump($softErrors);
28+
29+
?>
30+
--EXPECTF--
31+
URI parsing failed
32+
URL parsing failed
33+
string(23) "https://example.com/foo"
34+
array(%d) {
35+
[0]=>
36+
object(Uri\WhatWg\UrlValidationError)#%d (%d) {
37+
["context"]=>
38+
string(5) " /foo"
39+
["type"]=>
40+
enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
41+
["failure"]=>
42+
bool(false)
43+
}
44+
}

0 commit comments

Comments
 (0)