Skip to content

Commit 81865ec

Browse files
authored
uri: Improve exceptions for Uri\WhatWg\Url (#18855)
A more specific exception message is used, while the code is simplified.
1 parent 375316d commit 81865ec

File tree

6 files changed

+40
-41
lines changed

6 files changed

+40
-41
lines changed

ext/uri/php_lexbor.c

Lines changed: 32 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,21 @@ static void lexbor_cleanup_parser(void)
7373
* When errors is NULL, the caller is not interested in the additional error information,
7474
* so the function does nothing.
7575
*/
76-
static void fill_errors(zval *errors)
76+
static zend_string *fill_errors(zval *errors)
7777
{
7878
if (errors == NULL) {
79-
return;
79+
return NULL;
8080
}
8181

8282
ZEND_ASSERT(Z_ISUNDEF_P(errors));
8383

8484
array_init(errors);
8585

8686
if (lexbor_parser.log == NULL) {
87-
return;
87+
return NULL;
8888
}
8989

90+
zend_string *result = NULL;
9091
lexbor_plog_entry_t *lxb_error;
9192
while ((lxb_error = lexbor_array_obj_pop(&lexbor_parser.log->list)) != NULL) {
9293
zval error;
@@ -223,32 +224,29 @@ static void fill_errors(zval *errors)
223224

224225
zend_update_property(uri_whatwg_url_validation_error_ce, Z_OBJ(error), ZEND_STRL("failure"), &failure);
225226

227+
if (Z_TYPE(failure) == IS_TRUE) {
228+
result = error_str;
229+
}
230+
226231
add_next_index_zval(errors, &error);
227232
}
228-
}
229-
230-
static void throw_invalid_url_exception(zval *errors)
231-
{
232-
ZEND_ASSERT(errors != NULL && Z_TYPE_P(errors) == IS_ARRAY);
233-
234-
zval exception;
235-
236-
object_init_ex(&exception, uri_whatwg_invalid_url_exception_ce);
237-
238-
zval value;
239-
ZVAL_STRING(&value, "URL parsing failed");
240-
zend_update_property_ex(uri_whatwg_invalid_url_exception_ce, Z_OBJ(exception), ZSTR_KNOWN(ZEND_STR_MESSAGE), &value);
241-
zval_ptr_dtor_str(&value);
242-
243-
zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ(exception), ZEND_STRL("errors"), errors);
244233

245-
zend_throw_exception_object(&exception);
234+
return result;
246235
}
247236

248-
static void throw_invalid_url_exception_during_write(zval *errors)
237+
static void throw_invalid_url_exception_during_write(zval *errors, const char *component)
249238
{
250-
fill_errors(errors);
251-
throw_invalid_url_exception(errors);
239+
zend_string *reason = fill_errors(errors);
240+
zend_object *exception = zend_throw_exception_ex(
241+
uri_whatwg_invalid_url_exception_ce,
242+
0,
243+
"The specified %s is malformed%s%s%s",
244+
component,
245+
reason ? " (" : "",
246+
reason ? ZSTR_VAL(reason) : "",
247+
reason ? ")" : ""
248+
);
249+
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
252250
}
253251

254252
static lxb_status_t lexbor_serialize_callback(const lxb_char_t *data, size_t length, void *ctx)
@@ -281,7 +279,7 @@ static zend_result lexbor_write_scheme(struct uri_internal_t *internal_uri, zval
281279
zval_string_or_null_to_lexbor_str(value, &str);
282280

283281
if (lxb_url_api_protocol_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
284-
throw_invalid_url_exception_during_write(errors);
282+
throw_invalid_url_exception_during_write(errors, "scheme");
285283

286284
return FAILURE;
287285
}
@@ -310,7 +308,7 @@ static zend_result lexbor_write_username(uri_internal_t *internal_uri, zval *val
310308
zval_string_or_null_to_lexbor_str(value, &str);
311309

312310
if (lxb_url_api_username_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) {
313-
throw_invalid_url_exception_during_write(errors);
311+
throw_invalid_url_exception_during_write(errors, "username");
314312

315313
return FAILURE;
316314
}
@@ -339,7 +337,7 @@ static zend_result lexbor_write_password(struct uri_internal_t *internal_uri, zv
339337
zval_string_or_null_to_lexbor_str(value, &str);
340338

341339
if (lxb_url_api_password_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) {
342-
throw_invalid_url_exception_during_write(errors);
340+
throw_invalid_url_exception_during_write(errors, "password");
343341

344342
return FAILURE;
345343
}
@@ -411,7 +409,7 @@ static zend_result lexbor_write_host(struct uri_internal_t *internal_uri, zval *
411409
zval_string_or_null_to_lexbor_str(value, &str);
412410

413411
if (lxb_url_api_hostname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
414-
throw_invalid_url_exception_during_write(errors);
412+
throw_invalid_url_exception_during_write(errors, "host");
415413

416414
return FAILURE;
417415
}
@@ -440,7 +438,7 @@ static zend_result lexbor_write_port(struct uri_internal_t *internal_uri, zval *
440438
zval_long_or_null_to_lexbor_str(value, &str);
441439

442440
if (lxb_url_api_port_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
443-
throw_invalid_url_exception_during_write(errors);
441+
throw_invalid_url_exception_during_write(errors, "port");
444442

445443
return FAILURE;
446444
}
@@ -469,7 +467,7 @@ static zend_result lexbor_write_path(struct uri_internal_t *internal_uri, zval *
469467
zval_string_or_null_to_lexbor_str(value, &str);
470468

471469
if (lxb_url_api_pathname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
472-
throw_invalid_url_exception_during_write(errors);
470+
throw_invalid_url_exception_during_write(errors, "path");
473471

474472
return FAILURE;
475473
}
@@ -498,7 +496,7 @@ static zend_result lexbor_write_query(struct uri_internal_t *internal_uri, zval
498496
zval_string_or_null_to_lexbor_str(value, &str);
499497

500498
if (lxb_url_api_search_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
501-
throw_invalid_url_exception_during_write(errors);
499+
throw_invalid_url_exception_during_write(errors, "query string");
502500

503501
return FAILURE;
504502
}
@@ -527,7 +525,7 @@ static zend_result lexbor_write_fragment(struct uri_internal_t *internal_uri, zv
527525
zval_string_or_null_to_lexbor_str(value, &str);
528526

529527
if (lxb_url_api_hash_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
530-
throw_invalid_url_exception_during_write(errors);
528+
throw_invalid_url_exception_during_write(errors, "fragment");
531529

532530
return FAILURE;
533531
}
@@ -569,10 +567,11 @@ lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const lxb_url_t *lexb
569567
lexbor_cleanup_parser();
570568

571569
lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str));
572-
fill_errors(errors);
570+
zend_string *reason = fill_errors(errors);
573571

574572
if (url == NULL && !silent) {
575-
throw_invalid_url_exception(errors);
573+
zend_object *exception = zend_throw_exception_ex(uri_whatwg_invalid_url_exception_ce, 0, "The specified URI is malformed%s%s%s", reason ? " (" : "", reason ? ZSTR_VAL(reason) : "", reason ? ")" : "");
574+
zend_update_property(exception->ce, exception, ZEND_STRL("errors"), errors);
576575
}
577576

578577
return url;

ext/uri/tests/004.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ var_dump(Uri\WhatWg\Url::parse("192.168/contact.html", null));
1818
var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Cast on This Season's", null));
1919

2020
?>
21-
--EXPECTF--
22-
URL parsing failed
21+
--EXPECT--
22+
The specified URI is malformed (MissingSchemeNonRelativeUrl)
2323
NULL
2424
NULL
2525
NULL

ext/uri/tests/007.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ var_dump($failures);
1919

2020
?>
2121
--EXPECTF--
22-
URL parsing failed
22+
The specified URI is malformed (PortInvalid)
2323
array(%d) {
2424
[0]=>
2525
object(Uri\WhatWg\UrlValidationError)#%d (%d) {

ext/uri/tests/023.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,5 @@ try {
2727
--EXPECT--
2828
string(5) "https"
2929
string(4) "http"
30-
URL parsing failed
31-
URL parsing failed
30+
The specified scheme is malformed
31+
The specified scheme is malformed

ext/uri/tests/026.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ string(8) "test.com"
4343
string(8) "test.com"
4444
string(8) "test.com"
4545
NULL
46-
URL parsing failed
46+
The specified host is malformed (DomainInvalidCodePoint)
4747
object(Uri\WhatWg\Url)#%d (%d) {
4848
["scheme"]=>
4949
string(5) "https"
@@ -62,6 +62,6 @@ object(Uri\WhatWg\Url)#%d (%d) {
6262
["fragment"]=>
6363
NULL
6464
}
65-
URL parsing failed
65+
The specified host is malformed (HostMissing)
6666
string(7) "foo.com"
6767
string(8) "test.com"

ext/uri/tests/051.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ var_dump($softErrors);
2020

2121
?>
2222
--EXPECTF--
23-
URL parsing failed
23+
The specified URI is malformed (Ipv4TooManyParts)
2424
string(23) "https://example.com/foo"
2525
array(%d) {
2626
[0]=>

0 commit comments

Comments
 (0)