|
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,23 @@ 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 lxb_url_t *lexbor_base_url, zval *errors, bool silent) |
542 | 567 | { |
543 | 568 | lexbor_cleanup_parser(); |
544 | 569 |
|
545 | | - const lxb_url_t *lexbor_base_url = base_url; |
546 | 570 | lxb_url_t *url = lxb_url_parse(&lexbor_parser, lexbor_base_url, (unsigned char *) ZSTR_VAL(uri_str), ZSTR_LEN(uri_str)); |
547 | 571 | fill_errors(errors); |
548 | 572 |
|
| 573 | + if (url == NULL && !silent) { |
| 574 | + throw_invalid_url_exception(errors); |
| 575 | + } |
| 576 | + |
549 | 577 | return url; |
550 | 578 | } |
551 | 579 |
|
552 | | -static void lexbor_create_invalid_uri_exception(zval *exception_zv, zval *errors) |
| 580 | +static void *lexbor_parse_uri(const zend_string *uri_str, const void *base_url, zval *errors, bool silent) |
553 | 581 | { |
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); |
| 582 | + return lexbor_parse_uri_ex(uri_str, base_url, errors, silent); |
564 | 583 | } |
565 | 584 |
|
566 | 585 | static void *lexbor_clone_uri(void *uri) |
@@ -603,7 +622,6 @@ static void lexbor_free_uri(void *uri) |
603 | 622 | const uri_handler_t lexbor_uri_handler = { |
604 | 623 | .name = URI_PARSER_WHATWG, |
605 | 624 | .parse_uri = lexbor_parse_uri, |
606 | | - .create_invalid_uri_exception = lexbor_create_invalid_uri_exception, |
607 | 625 | .clone_uri = lexbor_clone_uri, |
608 | 626 | .uri_to_string = lexbor_uri_to_string, |
609 | 627 | .free_uri = lexbor_free_uri, |
|
0 commit comments