|
19 | 19 | #include "php_uri_common.h"
|
20 | 20 | #include "Zend/zend_enum.h"
|
21 | 21 | #include "Zend/zend_smart_str.h"
|
| 22 | +#include "Zend/zend_exceptions.h" |
22 | 23 | #ifdef HAVE_ARPA_INET_H
|
23 | 24 | #include <arpa/inet.h>
|
24 | 25 | #endif
|
@@ -225,6 +226,30 @@ static void fill_errors(zval *errors)
|
225 | 226 | }
|
226 | 227 | }
|
227 | 228 |
|
| 229 | +static void throw_invalid_url_exception(zval *errors) |
| 230 | +{ |
| 231 | + ZEND_ASSERT(errors != NULL && Z_TYPE_P(errors) == IS_ARRAY); |
| 232 | + |
| 233 | + zval exception; |
| 234 | + |
| 235 | + object_init_ex(&exception, uri_whatwg_invalid_url_exception_ce); |
| 236 | + |
| 237 | + zval value; |
| 238 | + ZVAL_STRING(&value, "URL parsing failed"); |
| 239 | + zend_update_property_ex(uri_whatwg_invalid_url_exception_ce, Z_OBJ(exception), ZSTR_KNOWN(ZEND_STR_MESSAGE), &value); |
| 240 | + zval_ptr_dtor_str(&value); |
| 241 | + |
| 242 | + zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ(exception), ZEND_STRL("errors"), errors); |
| 243 | + |
| 244 | + zend_throw_exception_object(&exception); |
| 245 | +} |
| 246 | + |
| 247 | +static void throw_invalid_url_exception_during_write(zval *errors) |
| 248 | +{ |
| 249 | + fill_errors(errors); |
| 250 | + throw_invalid_url_exception(errors); |
| 251 | +} |
| 252 | + |
228 | 253 | static lxb_status_t lexbor_serialize_callback(const lxb_char_t *data, size_t length, void *ctx)
|
229 | 254 | {
|
230 | 255 | smart_str *uri_str = ctx;
|
@@ -255,7 +280,7 @@ static zend_result lexbor_write_scheme(struct uri_internal_t *internal_uri, zval
|
255 | 280 | zval_string_or_null_to_lexbor_str(value, &str);
|
256 | 281 |
|
257 | 282 | if (lxb_url_api_protocol_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
258 |
| - fill_errors(errors); |
| 283 | + throw_invalid_url_exception_during_write(errors); |
259 | 284 |
|
260 | 285 | return FAILURE;
|
261 | 286 | }
|
@@ -284,7 +309,7 @@ static zend_result lexbor_write_username(uri_internal_t *internal_uri, zval *val
|
284 | 309 | zval_string_or_null_to_lexbor_str(value, &str);
|
285 | 310 |
|
286 | 311 | if (lxb_url_api_username_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) {
|
287 |
| - fill_errors(errors); |
| 312 | + throw_invalid_url_exception_during_write(errors); |
288 | 313 |
|
289 | 314 | return FAILURE;
|
290 | 315 | }
|
@@ -313,7 +338,7 @@ static zend_result lexbor_write_password(struct uri_internal_t *internal_uri, zv
|
313 | 338 | zval_string_or_null_to_lexbor_str(value, &str);
|
314 | 339 |
|
315 | 340 | if (lxb_url_api_password_set(lexbor_uri, str.data, str.length) != LXB_STATUS_OK) {
|
316 |
| - fill_errors(errors); |
| 341 | + throw_invalid_url_exception_during_write(errors); |
317 | 342 |
|
318 | 343 | return FAILURE;
|
319 | 344 | }
|
@@ -385,7 +410,7 @@ static zend_result lexbor_write_host(struct uri_internal_t *internal_uri, zval *
|
385 | 410 | zval_string_or_null_to_lexbor_str(value, &str);
|
386 | 411 |
|
387 | 412 | if (lxb_url_api_hostname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
388 |
| - fill_errors(errors); |
| 413 | + throw_invalid_url_exception_during_write(errors); |
389 | 414 |
|
390 | 415 | return FAILURE;
|
391 | 416 | }
|
@@ -414,7 +439,7 @@ static zend_result lexbor_write_port(struct uri_internal_t *internal_uri, zval *
|
414 | 439 | zval_long_or_null_to_lexbor_str(value, &str);
|
415 | 440 |
|
416 | 441 | if (lxb_url_api_port_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
417 |
| - fill_errors(errors); |
| 442 | + throw_invalid_url_exception_during_write(errors); |
418 | 443 |
|
419 | 444 | return FAILURE;
|
420 | 445 | }
|
@@ -443,7 +468,7 @@ static zend_result lexbor_write_path(struct uri_internal_t *internal_uri, zval *
|
443 | 468 | zval_string_or_null_to_lexbor_str(value, &str);
|
444 | 469 |
|
445 | 470 | if (lxb_url_api_pathname_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
446 |
| - fill_errors(errors); |
| 471 | + throw_invalid_url_exception_during_write(errors); |
447 | 472 |
|
448 | 473 | return FAILURE;
|
449 | 474 | }
|
@@ -472,7 +497,7 @@ static zend_result lexbor_write_query(struct uri_internal_t *internal_uri, zval
|
472 | 497 | zval_string_or_null_to_lexbor_str(value, &str);
|
473 | 498 |
|
474 | 499 | if (lxb_url_api_search_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
475 |
| - fill_errors(errors); |
| 500 | + throw_invalid_url_exception_during_write(errors); |
476 | 501 |
|
477 | 502 | return FAILURE;
|
478 | 503 | }
|
@@ -501,7 +526,7 @@ static zend_result lexbor_write_fragment(struct uri_internal_t *internal_uri, zv
|
501 | 526 | zval_string_or_null_to_lexbor_str(value, &str);
|
502 | 527 |
|
503 | 528 | if (lxb_url_api_hash_set(lexbor_uri, &lexbor_parser, str.data, str.length) != LXB_STATUS_OK) {
|
504 |
| - fill_errors(errors); |
| 529 | + throw_invalid_url_exception_during_write(errors); |
505 | 530 |
|
506 | 531 | return FAILURE;
|
507 | 532 | }
|
@@ -538,29 +563,24 @@ void lexbor_request_shutdown(void)
|
538 | 563 | lexbor_urls = 0;
|
539 | 564 | }
|
540 | 565 |
|
541 |
| -static void *lexbor_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors) |
| 566 | +lxb_url_t *lexbor_parse_uri_ex(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) |
542 | 567 | {
|
543 | 568 | lexbor_cleanup_parser();
|
544 | 569 |
|
545 | 570 | const lxb_url_t *lexbor_base_url = base_url;
|
546 | 571 | lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str));
|
547 | 572 | fill_errors(errors);
|
548 | 573 |
|
| 574 | + if (url == NULL && !silent) { |
| 575 | + throw_invalid_url_exception(errors); |
| 576 | + } |
| 577 | + |
549 | 578 | return url;
|
550 | 579 | }
|
551 | 580 |
|
552 |
| -static void lexbor_create_invalid_uri_exception(zval *exception_zv, zval *errors) |
| 581 | +static void *lexbor_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) |
553 | 582 | {
|
554 |
| - ZEND_ASSERT(Z_TYPE_P(errors) == IS_ARRAY && "Lexbor always returns an array of errors when URI parsing fails"); |
555 |
| - |
556 |
| - object_init_ex(exception_zv, uri_whatwg_invalid_url_exception_ce); |
557 |
| - |
558 |
| - zval value; |
559 |
| - ZVAL_STRING(&value, "URL parsing failed"); |
560 |
| - zend_update_property_ex(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(exception_zv), ZSTR_KNOWN(ZEND_STR_MESSAGE), &value); |
561 |
| - zval_ptr_dtor_str(&value); |
562 |
| - |
563 |
| - zend_update_property(uri_whatwg_invalid_url_exception_ce, Z_OBJ_P(exception_zv), ZEND_STRL("errors"), errors); |
| 583 | + return lexbor_parse_uri_ex(uri_str, base_url, errors, silent); |
564 | 584 | }
|
565 | 585 |
|
566 | 586 | static void *lexbor_clone_uri(void *uri)
|
@@ -603,7 +623,6 @@ static void lexbor_free_uri(void *uri)
|
603 | 623 | const uri_handler_t lexbor_uri_handler = {
|
604 | 624 | .name = URI_PARSER_WHATWG,
|
605 | 625 | .parse_uri = lexbor_parse_uri,
|
606 |
| - .create_invalid_uri_exception = lexbor_create_invalid_uri_exception, |
607 | 626 | .clone_uri = lexbor_clone_uri,
|
608 | 627 | .uri_to_string = lexbor_uri_to_string,
|
609 | 628 | .free_uri = lexbor_free_uri,
|
|
0 commit comments