From f2b9dd23c8defb19a3bc57c0424b5daac242d521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?M=C3=A1t=C3=A9=20Kocsis?= Date: Sat, 18 Jul 2026 13:31:47 +0200 Subject: [PATCH] Implement "Followup improvements for ext/uri" RFC - WHATWG URL percent-encoding RFC: https://wiki.php.net/rfc/uri_followup#percent-encoding_support --- ext/lexbor/lexbor/url/url.c | 304 +----------------- ext/lexbor/lexbor/url/url.h | 288 +++++++++++++++++ ext/uri/php_uri.c | 58 +++- ext/uri/php_uri.stub.php | 16 + ext/uri/php_uri_arginfo.h | 40 ++- ext/uri/php_uri_common.h | 1 + ext/uri/php_uri_decl.h | 21 +- .../form_query_success_control.phpt | 10 + .../form_query_success_percent.phpt | 10 + .../form_query_success_space.phpt | 10 + .../form_query_success_special_in_set.phpt | 10 + ...form_query_success_special_not_in_set.phpt | 10 + .../form_query_success_unicode.phpt | 10 + .../fragment_success_control.phpt | 10 + .../fragment_success_percent.phpt | 10 + .../fragment_success_special_in_set.phpt | 10 + .../fragment_success_special_not_in_set.phpt | 10 + .../fragment_success_unicode.phpt | 10 + .../opaque_host_success_control.phpt | 10 + .../opaque_host_success_percent.phpt | 10 + ...paque_host_success_special_not_in_set.phpt | 10 + .../opaque_host_success_unicode.phpt | 10 + .../opaque_path_success_control.phpt | 10 + .../opaque_path_success_percent.phpt | 10 + ...paque_path_success_special_not_in_set.phpt | 10 + .../opaque_path_success_unicode.phpt | 10 + .../password_segment_success_control.phpt | 10 + .../password_success_control.phpt | 10 + .../password_success_percent.phpt | 10 + .../password_success_special_in_set.phpt | 10 + .../password_success_special_not_in_set.phpt | 10 + .../password_success_unicode.phpt | 10 + .../path_segment_success_control.phpt | 10 + .../path_segment_success_percent.phpt | 10 + .../path_segment_success_special_in_set.phpt | 10 + ...th_segment_success_special_not_in_set.phpt | 10 + .../path_segment_success_unicode.phpt | 10 + .../path_success_control.phpt | 10 + .../path_success_percent.phpt | 10 + .../path_success_special_in_set.phpt | 10 + .../path_success_special_not_in_set.phpt | 10 + .../path_success_unicode.phpt | 10 + .../query_success_control.phpt | 10 + .../query_success_percent.phpt | 10 + .../percent_encoding/query_success_space.phpt | 10 + .../query_success_special_in_set.phpt | 10 + .../query_success_special_not_in_set.phpt | 10 + .../query_success_unicode.phpt | 10 + .../special_query_success_control.phpt | 10 + .../special_query_success_percent.phpt | 10 + .../special_query_success_space.phpt | 10 + .../special_query_success_special_in_set.phpt | 10 + ...cial_query_success_special_not_in_set.phpt | 10 + .../special_query_success_unicode.phpt | 10 + .../username_success_control.phpt | 10 + .../username_success_percent.phpt | 10 + .../username_success_special_in_set.phpt | 10 + .../username_success_special_not_in_set.phpt | 10 + .../username_success_unicode.phpt | 10 + ext/uri/uri_parser_whatwg.c | 149 +++++++++ ext/uri/uri_parser_whatwg.h | 10 + 61 files changed, 1113 insertions(+), 294 deletions(-) create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_space.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/form_query_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/fragment_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/fragment_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/fragment_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/fragment_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/fragment_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_host_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_host_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_host_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_host_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_path_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_path_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_path_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/opaque_path_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_segment_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/password_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_segment_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_segment_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_segment_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/path_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_space.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/query_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_space.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/special_query_success_unicode.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/username_success_control.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/username_success_percent.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/username_success_special_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/username_success_special_not_in_set.phpt create mode 100644 ext/uri/tests/whatwg/percent_encoding/username_success_unicode.phpt diff --git a/ext/lexbor/lexbor/url/url.c b/ext/lexbor/lexbor/url/url.c index 8099c12089bb..42cdf57440ac 100644 --- a/ext/lexbor/lexbor/url/url.c +++ b/ext/lexbor/lexbor/url/url.c @@ -26,21 +26,6 @@ #define LXB_URL_BUFFER_SIZE 4096 #define LXB_URL_BUFFER_NUM_SIZE 128 - -typedef enum { - LXB_URL_MAP_UNDEF = 0x00, - LXB_URL_MAP_C0 = 0x01, - LXB_URL_MAP_FRAGMENT = 0x02, - LXB_URL_MAP_QUERY = 0x04, - LXB_URL_MAP_SPECIAL_QUERY = 0x08, - LXB_URL_MAP_PATH = 0x10, - LXB_URL_MAP_USERINFO = 0x20, - LXB_URL_MAP_COMPONENT = 0x40, - LXB_URL_MAP_X_WWW_FORM = 0x80, - LXB_URL_MAP_ALL = 0xff -} -lxb_url_map_type_t; - typedef enum { LXB_URL_HOST_OPT_UNDEF = 0 << 0, LXB_URL_HOST_OPT_NOT_SPECIAL = 1 << 0, @@ -62,267 +47,6 @@ typedef struct { } lxb_url_search_params_ctx_t; - -static const uint8_t lxb_url_map[256] = -{ - LXB_URL_MAP_ALL, /* 0x00 */ - LXB_URL_MAP_ALL, /* 0x01 */ - LXB_URL_MAP_ALL, /* 0x02 */ - LXB_URL_MAP_ALL, /* 0x03 */ - LXB_URL_MAP_ALL, /* 0x04 */ - LXB_URL_MAP_ALL, /* 0x05 */ - LXB_URL_MAP_ALL, /* 0x06 */ - LXB_URL_MAP_ALL, /* 0x07 */ - LXB_URL_MAP_ALL, /* 0x08 */ - LXB_URL_MAP_ALL, /* 0x09 */ - LXB_URL_MAP_ALL, /* 0x0a */ - LXB_URL_MAP_ALL, /* 0x0b */ - LXB_URL_MAP_ALL, /* 0x0c */ - LXB_URL_MAP_ALL, /* 0x0d */ - LXB_URL_MAP_ALL, /* 0x0e */ - LXB_URL_MAP_ALL, /* 0x0f */ - LXB_URL_MAP_ALL, /* 0x10 */ - LXB_URL_MAP_ALL, /* 0x11 */ - LXB_URL_MAP_ALL, /* 0x12 */ - LXB_URL_MAP_ALL, /* 0x13 */ - LXB_URL_MAP_ALL, /* 0x14 */ - LXB_URL_MAP_ALL, /* 0x15 */ - LXB_URL_MAP_ALL, /* 0x16 */ - LXB_URL_MAP_ALL, /* 0x17 */ - LXB_URL_MAP_ALL, /* 0x18 */ - LXB_URL_MAP_ALL, /* 0x19 */ - LXB_URL_MAP_ALL, /* 0x1a */ - LXB_URL_MAP_ALL, /* 0x1b */ - LXB_URL_MAP_ALL, /* 0x1c */ - LXB_URL_MAP_ALL, /* 0x1d */ - LXB_URL_MAP_ALL, /* 0x1e */ - LXB_URL_MAP_ALL, /* 0x1f */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x20 ( ) */ - LXB_URL_MAP_X_WWW_FORM, /* 0x21 (!) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x22 (") */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x23 (#) */ - LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x24 ($) */ - LXB_URL_MAP_X_WWW_FORM, /* 0x25 (%) */ - LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x26 (&) */ - LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_X_WWW_FORM, /* 0x27 (') */ - LXB_URL_MAP_X_WWW_FORM, /* 0x28 (() */ - LXB_URL_MAP_X_WWW_FORM, /* 0x29 ()) */ - LXB_URL_MAP_UNDEF, /* 0x2a (*) */ - LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2b (+) */ - LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2c (,) */ - LXB_URL_MAP_UNDEF, /* 0x2d (-) */ - LXB_URL_MAP_UNDEF, /* 0x2e (.) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2f (/) */ - LXB_URL_MAP_UNDEF, /* 0x30 (0) */ - LXB_URL_MAP_UNDEF, /* 0x31 (1) */ - LXB_URL_MAP_UNDEF, /* 0x32 (2) */ - LXB_URL_MAP_UNDEF, /* 0x33 (3) */ - LXB_URL_MAP_UNDEF, /* 0x34 (4) */ - LXB_URL_MAP_UNDEF, /* 0x35 (5) */ - LXB_URL_MAP_UNDEF, /* 0x36 (6) */ - LXB_URL_MAP_UNDEF, /* 0x37 (7) */ - LXB_URL_MAP_UNDEF, /* 0x38 (8) */ - LXB_URL_MAP_UNDEF, /* 0x39 (9) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3a (:) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3b (;) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3c (<) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3d (=) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3e (>) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3f (?) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x40 (@) */ - LXB_URL_MAP_UNDEF, /* 0x41 (A) */ - LXB_URL_MAP_UNDEF, /* 0x42 (B) */ - LXB_URL_MAP_UNDEF, /* 0x43 (C) */ - LXB_URL_MAP_UNDEF, /* 0x44 (D) */ - LXB_URL_MAP_UNDEF, /* 0x45 (E) */ - LXB_URL_MAP_UNDEF, /* 0x46 (F) */ - LXB_URL_MAP_UNDEF, /* 0x47 (G) */ - LXB_URL_MAP_UNDEF, /* 0x48 (H) */ - LXB_URL_MAP_UNDEF, /* 0x49 (I) */ - LXB_URL_MAP_UNDEF, /* 0x4a (J) */ - LXB_URL_MAP_UNDEF, /* 0x4b (K) */ - LXB_URL_MAP_UNDEF, /* 0x4c (L) */ - LXB_URL_MAP_UNDEF, /* 0x4d (M) */ - LXB_URL_MAP_UNDEF, /* 0x4e (N) */ - LXB_URL_MAP_UNDEF, /* 0x4f (O) */ - LXB_URL_MAP_UNDEF, /* 0x50 (P) */ - LXB_URL_MAP_UNDEF, /* 0x51 (Q) */ - LXB_URL_MAP_UNDEF, /* 0x52 (R) */ - LXB_URL_MAP_UNDEF, /* 0x53 (S) */ - LXB_URL_MAP_UNDEF, /* 0x54 (T) */ - LXB_URL_MAP_UNDEF, /* 0x55 (U) */ - LXB_URL_MAP_UNDEF, /* 0x56 (V) */ - LXB_URL_MAP_UNDEF, /* 0x57 (W) */ - LXB_URL_MAP_UNDEF, /* 0x58 (X) */ - LXB_URL_MAP_UNDEF, /* 0x59 (Y) */ - LXB_URL_MAP_UNDEF, /* 0x5a (Z) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5b ([) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5c (\) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5d (]) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ - LXB_URL_MAP_UNDEF, /* 0x5f (_) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x60 (`) */ - LXB_URL_MAP_UNDEF, /* 0x61 (a) */ - LXB_URL_MAP_UNDEF, /* 0x62 (b) */ - LXB_URL_MAP_UNDEF, /* 0x63 (c) */ - LXB_URL_MAP_UNDEF, /* 0x64 (d) */ - LXB_URL_MAP_UNDEF, /* 0x65 (e) */ - LXB_URL_MAP_UNDEF, /* 0x66 (f) */ - LXB_URL_MAP_UNDEF, /* 0x67 (g) */ - LXB_URL_MAP_UNDEF, /* 0x68 (h) */ - LXB_URL_MAP_UNDEF, /* 0x69 (i) */ - LXB_URL_MAP_UNDEF, /* 0x6a (j) */ - LXB_URL_MAP_UNDEF, /* 0x6b (k) */ - LXB_URL_MAP_UNDEF, /* 0x6c (l) */ - LXB_URL_MAP_UNDEF, /* 0x6d (m) */ - LXB_URL_MAP_UNDEF, /* 0x6e (n) */ - LXB_URL_MAP_UNDEF, /* 0x6f (o) */ - LXB_URL_MAP_UNDEF, /* 0x70 (p) */ - LXB_URL_MAP_UNDEF, /* 0x71 (q) */ - LXB_URL_MAP_UNDEF, /* 0x72 (r) */ - LXB_URL_MAP_UNDEF, /* 0x73 (s) */ - LXB_URL_MAP_UNDEF, /* 0x74 (t) */ - LXB_URL_MAP_UNDEF, /* 0x75 (u) */ - LXB_URL_MAP_UNDEF, /* 0x76 (v) */ - LXB_URL_MAP_UNDEF, /* 0x77 (w) */ - LXB_URL_MAP_UNDEF, /* 0x78 (x) */ - LXB_URL_MAP_UNDEF, /* 0x79 (y) */ - LXB_URL_MAP_UNDEF, /* 0x7a (z) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7b ({) */ - LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7c (|) */ - LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7d (}) */ - LXB_URL_MAP_X_WWW_FORM, /* 0x7e (~) */ - LXB_URL_MAP_ALL, /* 0x7f */ - LXB_URL_MAP_ALL, /* 0x80 */ - LXB_URL_MAP_ALL, /* 0x81 */ - LXB_URL_MAP_ALL, /* 0x82 */ - LXB_URL_MAP_ALL, /* 0x83 */ - LXB_URL_MAP_ALL, /* 0x84 */ - LXB_URL_MAP_ALL, /* 0x85 */ - LXB_URL_MAP_ALL, /* 0x86 */ - LXB_URL_MAP_ALL, /* 0x87 */ - LXB_URL_MAP_ALL, /* 0x88 */ - LXB_URL_MAP_ALL, /* 0x89 */ - LXB_URL_MAP_ALL, /* 0x8a */ - LXB_URL_MAP_ALL, /* 0x8b */ - LXB_URL_MAP_ALL, /* 0x8c */ - LXB_URL_MAP_ALL, /* 0x8d */ - LXB_URL_MAP_ALL, /* 0x8e */ - LXB_URL_MAP_ALL, /* 0x8f */ - LXB_URL_MAP_ALL, /* 0x90 */ - LXB_URL_MAP_ALL, /* 0x91 */ - LXB_URL_MAP_ALL, /* 0x92 */ - LXB_URL_MAP_ALL, /* 0x93 */ - LXB_URL_MAP_ALL, /* 0x94 */ - LXB_URL_MAP_ALL, /* 0x95 */ - LXB_URL_MAP_ALL, /* 0x96 */ - LXB_URL_MAP_ALL, /* 0x97 */ - LXB_URL_MAP_ALL, /* 0x98 */ - LXB_URL_MAP_ALL, /* 0x99 */ - LXB_URL_MAP_ALL, /* 0x9a */ - LXB_URL_MAP_ALL, /* 0x9b */ - LXB_URL_MAP_ALL, /* 0x9c */ - LXB_URL_MAP_ALL, /* 0x9d */ - LXB_URL_MAP_ALL, /* 0x9e */ - LXB_URL_MAP_ALL, /* 0x9f */ - LXB_URL_MAP_ALL, /* 0xa0 */ - LXB_URL_MAP_ALL, /* 0xa1 */ - LXB_URL_MAP_ALL, /* 0xa2 */ - LXB_URL_MAP_ALL, /* 0xa3 */ - LXB_URL_MAP_ALL, /* 0xa4 */ - LXB_URL_MAP_ALL, /* 0xa5 */ - LXB_URL_MAP_ALL, /* 0xa6 */ - LXB_URL_MAP_ALL, /* 0xa7 */ - LXB_URL_MAP_ALL, /* 0xa8 */ - LXB_URL_MAP_ALL, /* 0xa9 */ - LXB_URL_MAP_ALL, /* 0xaa */ - LXB_URL_MAP_ALL, /* 0xab */ - LXB_URL_MAP_ALL, /* 0xac */ - LXB_URL_MAP_ALL, /* 0xad */ - LXB_URL_MAP_ALL, /* 0xae */ - LXB_URL_MAP_ALL, /* 0xaf */ - LXB_URL_MAP_ALL, /* 0xb0 */ - LXB_URL_MAP_ALL, /* 0xb1 */ - LXB_URL_MAP_ALL, /* 0xb2 */ - LXB_URL_MAP_ALL, /* 0xb3 */ - LXB_URL_MAP_ALL, /* 0xb4 */ - LXB_URL_MAP_ALL, /* 0xb5 */ - LXB_URL_MAP_ALL, /* 0xb6 */ - LXB_URL_MAP_ALL, /* 0xb7 */ - LXB_URL_MAP_ALL, /* 0xb8 */ - LXB_URL_MAP_ALL, /* 0xb9 */ - LXB_URL_MAP_ALL, /* 0xba */ - LXB_URL_MAP_ALL, /* 0xbb */ - LXB_URL_MAP_ALL, /* 0xbc */ - LXB_URL_MAP_ALL, /* 0xbd */ - LXB_URL_MAP_ALL, /* 0xbe */ - LXB_URL_MAP_ALL, /* 0xbf */ - LXB_URL_MAP_ALL, /* 0xc0 */ - LXB_URL_MAP_ALL, /* 0xc1 */ - LXB_URL_MAP_ALL, /* 0xc2 */ - LXB_URL_MAP_ALL, /* 0xc3 */ - LXB_URL_MAP_ALL, /* 0xc4 */ - LXB_URL_MAP_ALL, /* 0xc5 */ - LXB_URL_MAP_ALL, /* 0xc6 */ - LXB_URL_MAP_ALL, /* 0xc7 */ - LXB_URL_MAP_ALL, /* 0xc8 */ - LXB_URL_MAP_ALL, /* 0xc9 */ - LXB_URL_MAP_ALL, /* 0xca */ - LXB_URL_MAP_ALL, /* 0xcb */ - LXB_URL_MAP_ALL, /* 0xcc */ - LXB_URL_MAP_ALL, /* 0xcd */ - LXB_URL_MAP_ALL, /* 0xce */ - LXB_URL_MAP_ALL, /* 0xcf */ - LXB_URL_MAP_ALL, /* 0xd0 */ - LXB_URL_MAP_ALL, /* 0xd1 */ - LXB_URL_MAP_ALL, /* 0xd2 */ - LXB_URL_MAP_ALL, /* 0xd3 */ - LXB_URL_MAP_ALL, /* 0xd4 */ - LXB_URL_MAP_ALL, /* 0xd5 */ - LXB_URL_MAP_ALL, /* 0xd6 */ - LXB_URL_MAP_ALL, /* 0xd7 */ - LXB_URL_MAP_ALL, /* 0xd8 */ - LXB_URL_MAP_ALL, /* 0xd9 */ - LXB_URL_MAP_ALL, /* 0xda */ - LXB_URL_MAP_ALL, /* 0xdb */ - LXB_URL_MAP_ALL, /* 0xdc */ - LXB_URL_MAP_ALL, /* 0xdd */ - LXB_URL_MAP_ALL, /* 0xde */ - LXB_URL_MAP_ALL, /* 0xdf */ - LXB_URL_MAP_ALL, /* 0xe0 */ - LXB_URL_MAP_ALL, /* 0xe1 */ - LXB_URL_MAP_ALL, /* 0xe2 */ - LXB_URL_MAP_ALL, /* 0xe3 */ - LXB_URL_MAP_ALL, /* 0xe4 */ - LXB_URL_MAP_ALL, /* 0xe5 */ - LXB_URL_MAP_ALL, /* 0xe6 */ - LXB_URL_MAP_ALL, /* 0xe7 */ - LXB_URL_MAP_ALL, /* 0xe8 */ - LXB_URL_MAP_ALL, /* 0xe9 */ - LXB_URL_MAP_ALL, /* 0xea */ - LXB_URL_MAP_ALL, /* 0xeb */ - LXB_URL_MAP_ALL, /* 0xec */ - LXB_URL_MAP_ALL, /* 0xed */ - LXB_URL_MAP_ALL, /* 0xee */ - LXB_URL_MAP_ALL, /* 0xef */ - LXB_URL_MAP_ALL, /* 0xf0 */ - LXB_URL_MAP_ALL, /* 0xf1 */ - LXB_URL_MAP_ALL, /* 0xf2 */ - LXB_URL_MAP_ALL, /* 0xf3 */ - LXB_URL_MAP_ALL, /* 0xf4 */ - LXB_URL_MAP_ALL, /* 0xf5 */ - LXB_URL_MAP_ALL, /* 0xf6 */ - LXB_URL_MAP_ALL, /* 0xf7 */ - LXB_URL_MAP_ALL, /* 0xf8 */ - LXB_URL_MAP_ALL, /* 0xf9 */ - LXB_URL_MAP_ALL, /* 0xfa */ - LXB_URL_MAP_ALL, /* 0xfb */ - LXB_URL_MAP_ALL, /* 0xfc */ - LXB_URL_MAP_ALL, /* 0xfd */ - LXB_URL_MAP_ALL, /* 0xfe */ - LXB_URL_MAP_ALL, /* 0xff */ -}; - /* * U+0000 NULL, U+0009 TAB, U+000A LF, U+000D CR, U+0020 SPACE, U+0023 (#), * U+002F (/), U+003A (:), U+003C (<), U+003E (>), U+003F (?), U+0040 (@), @@ -568,13 +292,6 @@ lxb_url_percent_encode_after_encoding(const lxb_char_t *data, lxb_url_map_type_t enmap, bool space_as_plus); -static lxb_status_t -lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, - const lxb_char_t *end, lexbor_str_t *str, - lexbor_mraw_t *mraw, - lxb_url_map_type_t enmap, - bool space_as_plus); - static lxb_status_t lxb_url_host_parse(lxb_url_parser_t *parser, const lxb_char_t *data, const lxb_char_t *end, lxb_url_host_t *host, @@ -3280,12 +2997,13 @@ lxb_url_percent_encode_after_encoding(const lxb_char_t *data, return LXB_STATUS_OK; } -static lxb_status_t -lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, +lxb_status_t +lxb_url_percent_encode_after_utf_8_ex(const lxb_char_t *data, const lxb_char_t *end, lexbor_str_t *str, lexbor_mraw_t *mraw, lxb_url_map_type_t enmap, - bool space_as_plus) + bool space_as_plus, + const uint8_t *url_map) { size_t length; lxb_status_t status; @@ -3298,7 +3016,7 @@ lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, /* Only valid for UTF-8. */ while (p < end) { - if (lxb_url_map[*p++] & enmap) { + if (url_map[*p++] & enmap) { length += 2; } } @@ -3317,7 +3035,7 @@ lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, if (space_as_plus && c == ' ') { *pd++ = '+'; } - else if (lxb_url_map[c] & enmap) { + else if (url_map[c] & enmap) { *pd++ = '%'; *pd++ = lexbor_str_res_char_to_two_hex_value[c][0]; *pd++ = lexbor_str_res_char_to_two_hex_value[c][1]; @@ -3335,6 +3053,16 @@ lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, return LXB_STATUS_OK; } +lxb_status_t +lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, + const lxb_char_t *end, lexbor_str_t *str, + lexbor_mraw_t *mraw, + lxb_url_map_type_t enmap, + bool space_as_plus) +{ + return lxb_url_percent_encode_after_utf_8_ex(data, end, str, mraw, enmap, space_as_plus, lxb_url_map); +} + static lxb_status_t lxb_url_host_parse(lxb_url_parser_t *parser, const lxb_char_t *data, const lxb_char_t *end, lxb_url_host_t *host, diff --git a/ext/lexbor/lexbor/url/url.h b/ext/lexbor/lexbor/url/url.h index 6cc6f1081c8a..616bc76aedbb 100644 --- a/ext/lexbor/lexbor/url/url.h +++ b/ext/lexbor/lexbor/url/url.h @@ -20,6 +20,279 @@ extern "C" { #include "lexbor/encoding/encoding.h" #include "lexbor/unicode/unicode.h" +typedef enum { + LXB_URL_MAP_UNDEF = 0x00, + LXB_URL_MAP_C0 = 0x01, + LXB_URL_MAP_FRAGMENT = 0x02, + LXB_URL_MAP_QUERY = 0x04, + LXB_URL_MAP_SPECIAL_QUERY = 0x08, + LXB_URL_MAP_PATH = 0x10, + LXB_URL_MAP_USERINFO = 0x20, + LXB_URL_MAP_COMPONENT = 0x40, + LXB_URL_MAP_X_WWW_FORM = 0x80, + LXB_URL_MAP_ALL = 0xff +} +lxb_url_map_type_t; + +static const uint8_t lxb_url_map[256] = +{ + LXB_URL_MAP_ALL, /* 0x00 */ + LXB_URL_MAP_ALL, /* 0x01 */ + LXB_URL_MAP_ALL, /* 0x02 */ + LXB_URL_MAP_ALL, /* 0x03 */ + LXB_URL_MAP_ALL, /* 0x04 */ + LXB_URL_MAP_ALL, /* 0x05 */ + LXB_URL_MAP_ALL, /* 0x06 */ + LXB_URL_MAP_ALL, /* 0x07 */ + LXB_URL_MAP_ALL, /* 0x08 */ + LXB_URL_MAP_ALL, /* 0x09 */ + LXB_URL_MAP_ALL, /* 0x0a */ + LXB_URL_MAP_ALL, /* 0x0b */ + LXB_URL_MAP_ALL, /* 0x0c */ + LXB_URL_MAP_ALL, /* 0x0d */ + LXB_URL_MAP_ALL, /* 0x0e */ + LXB_URL_MAP_ALL, /* 0x0f */ + LXB_URL_MAP_ALL, /* 0x10 */ + LXB_URL_MAP_ALL, /* 0x11 */ + LXB_URL_MAP_ALL, /* 0x12 */ + LXB_URL_MAP_ALL, /* 0x13 */ + LXB_URL_MAP_ALL, /* 0x14 */ + LXB_URL_MAP_ALL, /* 0x15 */ + LXB_URL_MAP_ALL, /* 0x16 */ + LXB_URL_MAP_ALL, /* 0x17 */ + LXB_URL_MAP_ALL, /* 0x18 */ + LXB_URL_MAP_ALL, /* 0x19 */ + LXB_URL_MAP_ALL, /* 0x1a */ + LXB_URL_MAP_ALL, /* 0x1b */ + LXB_URL_MAP_ALL, /* 0x1c */ + LXB_URL_MAP_ALL, /* 0x1d */ + LXB_URL_MAP_ALL, /* 0x1e */ + LXB_URL_MAP_ALL, /* 0x1f */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x20 ( ) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x21 (!) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x22 (") */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x23 (#) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x24 ($) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x25 (%) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x26 (&) */ + LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_X_WWW_FORM, /* 0x27 (') */ + LXB_URL_MAP_X_WWW_FORM, /* 0x28 (() */ + LXB_URL_MAP_X_WWW_FORM, /* 0x29 ()) */ + LXB_URL_MAP_UNDEF, /* 0x2a (*) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2b (+) */ + LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2c (,) */ + LXB_URL_MAP_UNDEF, /* 0x2d (-) */ + LXB_URL_MAP_UNDEF, /* 0x2e (.) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x2f (/) */ + LXB_URL_MAP_UNDEF, /* 0x30 (0) */ + LXB_URL_MAP_UNDEF, /* 0x31 (1) */ + LXB_URL_MAP_UNDEF, /* 0x32 (2) */ + LXB_URL_MAP_UNDEF, /* 0x33 (3) */ + LXB_URL_MAP_UNDEF, /* 0x34 (4) */ + LXB_URL_MAP_UNDEF, /* 0x35 (5) */ + LXB_URL_MAP_UNDEF, /* 0x36 (6) */ + LXB_URL_MAP_UNDEF, /* 0x37 (7) */ + LXB_URL_MAP_UNDEF, /* 0x38 (8) */ + LXB_URL_MAP_UNDEF, /* 0x39 (9) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3a (:) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3b (;) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3c (<) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3d (=) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_QUERY|LXB_URL_MAP_SPECIAL_QUERY|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3e (>) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x3f (?) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x40 (@) */ + LXB_URL_MAP_UNDEF, /* 0x41 (A) */ + LXB_URL_MAP_UNDEF, /* 0x42 (B) */ + LXB_URL_MAP_UNDEF, /* 0x43 (C) */ + LXB_URL_MAP_UNDEF, /* 0x44 (D) */ + LXB_URL_MAP_UNDEF, /* 0x45 (E) */ + LXB_URL_MAP_UNDEF, /* 0x46 (F) */ + LXB_URL_MAP_UNDEF, /* 0x47 (G) */ + LXB_URL_MAP_UNDEF, /* 0x48 (H) */ + LXB_URL_MAP_UNDEF, /* 0x49 (I) */ + LXB_URL_MAP_UNDEF, /* 0x4a (J) */ + LXB_URL_MAP_UNDEF, /* 0x4b (K) */ + LXB_URL_MAP_UNDEF, /* 0x4c (L) */ + LXB_URL_MAP_UNDEF, /* 0x4d (M) */ + LXB_URL_MAP_UNDEF, /* 0x4e (N) */ + LXB_URL_MAP_UNDEF, /* 0x4f (O) */ + LXB_URL_MAP_UNDEF, /* 0x50 (P) */ + LXB_URL_MAP_UNDEF, /* 0x51 (Q) */ + LXB_URL_MAP_UNDEF, /* 0x52 (R) */ + LXB_URL_MAP_UNDEF, /* 0x53 (S) */ + LXB_URL_MAP_UNDEF, /* 0x54 (T) */ + LXB_URL_MAP_UNDEF, /* 0x55 (U) */ + LXB_URL_MAP_UNDEF, /* 0x56 (V) */ + LXB_URL_MAP_UNDEF, /* 0x57 (W) */ + LXB_URL_MAP_UNDEF, /* 0x58 (X) */ + LXB_URL_MAP_UNDEF, /* 0x59 (Y) */ + LXB_URL_MAP_UNDEF, /* 0x5a (Z) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5b ([) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5c (\) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5d (]) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_PATH|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x5e (^) */ + LXB_URL_MAP_UNDEF, /* 0x5f (_) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_FRAGMENT|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x60 (`) */ + LXB_URL_MAP_UNDEF, /* 0x61 (a) */ + LXB_URL_MAP_UNDEF, /* 0x62 (b) */ + LXB_URL_MAP_UNDEF, /* 0x63 (c) */ + LXB_URL_MAP_UNDEF, /* 0x64 (d) */ + LXB_URL_MAP_UNDEF, /* 0x65 (e) */ + LXB_URL_MAP_UNDEF, /* 0x66 (f) */ + LXB_URL_MAP_UNDEF, /* 0x67 (g) */ + LXB_URL_MAP_UNDEF, /* 0x68 (h) */ + LXB_URL_MAP_UNDEF, /* 0x69 (i) */ + LXB_URL_MAP_UNDEF, /* 0x6a (j) */ + LXB_URL_MAP_UNDEF, /* 0x6b (k) */ + LXB_URL_MAP_UNDEF, /* 0x6c (l) */ + LXB_URL_MAP_UNDEF, /* 0x6d (m) */ + LXB_URL_MAP_UNDEF, /* 0x6e (n) */ + LXB_URL_MAP_UNDEF, /* 0x6f (o) */ + LXB_URL_MAP_UNDEF, /* 0x70 (p) */ + LXB_URL_MAP_UNDEF, /* 0x71 (q) */ + LXB_URL_MAP_UNDEF, /* 0x72 (r) */ + LXB_URL_MAP_UNDEF, /* 0x73 (s) */ + LXB_URL_MAP_UNDEF, /* 0x74 (t) */ + LXB_URL_MAP_UNDEF, /* 0x75 (u) */ + LXB_URL_MAP_UNDEF, /* 0x76 (v) */ + LXB_URL_MAP_UNDEF, /* 0x77 (w) */ + LXB_URL_MAP_UNDEF, /* 0x78 (x) */ + LXB_URL_MAP_UNDEF, /* 0x79 (y) */ + LXB_URL_MAP_UNDEF, /* 0x7a (z) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7b ({) */ + LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7c (|) */ + LXB_URL_MAP_PATH|LXB_URL_MAP_USERINFO|LXB_URL_MAP_COMPONENT|LXB_URL_MAP_X_WWW_FORM, /* 0x7d (}) */ + LXB_URL_MAP_X_WWW_FORM, /* 0x7e (~) */ + LXB_URL_MAP_ALL, /* 0x7f */ + LXB_URL_MAP_ALL, /* 0x80 */ + LXB_URL_MAP_ALL, /* 0x81 */ + LXB_URL_MAP_ALL, /* 0x82 */ + LXB_URL_MAP_ALL, /* 0x83 */ + LXB_URL_MAP_ALL, /* 0x84 */ + LXB_URL_MAP_ALL, /* 0x85 */ + LXB_URL_MAP_ALL, /* 0x86 */ + LXB_URL_MAP_ALL, /* 0x87 */ + LXB_URL_MAP_ALL, /* 0x88 */ + LXB_URL_MAP_ALL, /* 0x89 */ + LXB_URL_MAP_ALL, /* 0x8a */ + LXB_URL_MAP_ALL, /* 0x8b */ + LXB_URL_MAP_ALL, /* 0x8c */ + LXB_URL_MAP_ALL, /* 0x8d */ + LXB_URL_MAP_ALL, /* 0x8e */ + LXB_URL_MAP_ALL, /* 0x8f */ + LXB_URL_MAP_ALL, /* 0x90 */ + LXB_URL_MAP_ALL, /* 0x91 */ + LXB_URL_MAP_ALL, /* 0x92 */ + LXB_URL_MAP_ALL, /* 0x93 */ + LXB_URL_MAP_ALL, /* 0x94 */ + LXB_URL_MAP_ALL, /* 0x95 */ + LXB_URL_MAP_ALL, /* 0x96 */ + LXB_URL_MAP_ALL, /* 0x97 */ + LXB_URL_MAP_ALL, /* 0x98 */ + LXB_URL_MAP_ALL, /* 0x99 */ + LXB_URL_MAP_ALL, /* 0x9a */ + LXB_URL_MAP_ALL, /* 0x9b */ + LXB_URL_MAP_ALL, /* 0x9c */ + LXB_URL_MAP_ALL, /* 0x9d */ + LXB_URL_MAP_ALL, /* 0x9e */ + LXB_URL_MAP_ALL, /* 0x9f */ + LXB_URL_MAP_ALL, /* 0xa0 */ + LXB_URL_MAP_ALL, /* 0xa1 */ + LXB_URL_MAP_ALL, /* 0xa2 */ + LXB_URL_MAP_ALL, /* 0xa3 */ + LXB_URL_MAP_ALL, /* 0xa4 */ + LXB_URL_MAP_ALL, /* 0xa5 */ + LXB_URL_MAP_ALL, /* 0xa6 */ + LXB_URL_MAP_ALL, /* 0xa7 */ + LXB_URL_MAP_ALL, /* 0xa8 */ + LXB_URL_MAP_ALL, /* 0xa9 */ + LXB_URL_MAP_ALL, /* 0xaa */ + LXB_URL_MAP_ALL, /* 0xab */ + LXB_URL_MAP_ALL, /* 0xac */ + LXB_URL_MAP_ALL, /* 0xad */ + LXB_URL_MAP_ALL, /* 0xae */ + LXB_URL_MAP_ALL, /* 0xaf */ + LXB_URL_MAP_ALL, /* 0xb0 */ + LXB_URL_MAP_ALL, /* 0xb1 */ + LXB_URL_MAP_ALL, /* 0xb2 */ + LXB_URL_MAP_ALL, /* 0xb3 */ + LXB_URL_MAP_ALL, /* 0xb4 */ + LXB_URL_MAP_ALL, /* 0xb5 */ + LXB_URL_MAP_ALL, /* 0xb6 */ + LXB_URL_MAP_ALL, /* 0xb7 */ + LXB_URL_MAP_ALL, /* 0xb8 */ + LXB_URL_MAP_ALL, /* 0xb9 */ + LXB_URL_MAP_ALL, /* 0xba */ + LXB_URL_MAP_ALL, /* 0xbb */ + LXB_URL_MAP_ALL, /* 0xbc */ + LXB_URL_MAP_ALL, /* 0xbd */ + LXB_URL_MAP_ALL, /* 0xbe */ + LXB_URL_MAP_ALL, /* 0xbf */ + LXB_URL_MAP_ALL, /* 0xc0 */ + LXB_URL_MAP_ALL, /* 0xc1 */ + LXB_URL_MAP_ALL, /* 0xc2 */ + LXB_URL_MAP_ALL, /* 0xc3 */ + LXB_URL_MAP_ALL, /* 0xc4 */ + LXB_URL_MAP_ALL, /* 0xc5 */ + LXB_URL_MAP_ALL, /* 0xc6 */ + LXB_URL_MAP_ALL, /* 0xc7 */ + LXB_URL_MAP_ALL, /* 0xc8 */ + LXB_URL_MAP_ALL, /* 0xc9 */ + LXB_URL_MAP_ALL, /* 0xca */ + LXB_URL_MAP_ALL, /* 0xcb */ + LXB_URL_MAP_ALL, /* 0xcc */ + LXB_URL_MAP_ALL, /* 0xcd */ + LXB_URL_MAP_ALL, /* 0xce */ + LXB_URL_MAP_ALL, /* 0xcf */ + LXB_URL_MAP_ALL, /* 0xd0 */ + LXB_URL_MAP_ALL, /* 0xd1 */ + LXB_URL_MAP_ALL, /* 0xd2 */ + LXB_URL_MAP_ALL, /* 0xd3 */ + LXB_URL_MAP_ALL, /* 0xd4 */ + LXB_URL_MAP_ALL, /* 0xd5 */ + LXB_URL_MAP_ALL, /* 0xd6 */ + LXB_URL_MAP_ALL, /* 0xd7 */ + LXB_URL_MAP_ALL, /* 0xd8 */ + LXB_URL_MAP_ALL, /* 0xd9 */ + LXB_URL_MAP_ALL, /* 0xda */ + LXB_URL_MAP_ALL, /* 0xdb */ + LXB_URL_MAP_ALL, /* 0xdc */ + LXB_URL_MAP_ALL, /* 0xdd */ + LXB_URL_MAP_ALL, /* 0xde */ + LXB_URL_MAP_ALL, /* 0xdf */ + LXB_URL_MAP_ALL, /* 0xe0 */ + LXB_URL_MAP_ALL, /* 0xe1 */ + LXB_URL_MAP_ALL, /* 0xe2 */ + LXB_URL_MAP_ALL, /* 0xe3 */ + LXB_URL_MAP_ALL, /* 0xe4 */ + LXB_URL_MAP_ALL, /* 0xe5 */ + LXB_URL_MAP_ALL, /* 0xe6 */ + LXB_URL_MAP_ALL, /* 0xe7 */ + LXB_URL_MAP_ALL, /* 0xe8 */ + LXB_URL_MAP_ALL, /* 0xe9 */ + LXB_URL_MAP_ALL, /* 0xea */ + LXB_URL_MAP_ALL, /* 0xeb */ + LXB_URL_MAP_ALL, /* 0xec */ + LXB_URL_MAP_ALL, /* 0xed */ + LXB_URL_MAP_ALL, /* 0xee */ + LXB_URL_MAP_ALL, /* 0xef */ + LXB_URL_MAP_ALL, /* 0xf0 */ + LXB_URL_MAP_ALL, /* 0xf1 */ + LXB_URL_MAP_ALL, /* 0xf2 */ + LXB_URL_MAP_ALL, /* 0xf3 */ + LXB_URL_MAP_ALL, /* 0xf4 */ + LXB_URL_MAP_ALL, /* 0xf5 */ + LXB_URL_MAP_ALL, /* 0xf6 */ + LXB_URL_MAP_ALL, /* 0xf7 */ + LXB_URL_MAP_ALL, /* 0xf8 */ + LXB_URL_MAP_ALL, /* 0xf9 */ + LXB_URL_MAP_ALL, /* 0xfa */ + LXB_URL_MAP_ALL, /* 0xfb */ + LXB_URL_MAP_ALL, /* 0xfc */ + LXB_URL_MAP_ALL, /* 0xfd */ + LXB_URL_MAP_ALL, /* 0xfe */ + LXB_URL_MAP_ALL, /* 0xff */ +}; typedef enum { LXB_URL_ERROR_TYPE_DOMAIN_TO_ASCII = 0x00, @@ -280,6 +553,21 @@ lxb_url_parser_destroy(lxb_url_parser_t *parser, bool destroy_self); LXB_API void lxb_url_parser_memory_destroy(lxb_url_parser_t *parser); +lxb_status_t +lxb_url_percent_encode_after_utf_8_ex(const lxb_char_t *data, + const lxb_char_t *end, lexbor_str_t *str, + lexbor_mraw_t *mraw, + lxb_url_map_type_t enmap, + bool space_as_plus, + const uint8_t *url_map); + +lxb_status_t +lxb_url_percent_encode_after_utf_8(const lxb_char_t *data, + const lxb_char_t *end, lexbor_str_t *str, + lexbor_mraw_t *mraw, + lxb_url_map_type_t enmap, + bool space_as_plus); + /* * URL parser. * diff --git a/ext/uri/php_uri.c b/ext/uri/php_uri.c index 74a559fd591c..c9f7b40ab358 100644 --- a/ext/uri/php_uri.c +++ b/ext/uri/php_uri.c @@ -35,6 +35,7 @@ zend_class_entry *php_uri_ce_rfc3986_uri; zend_class_entry *php_uri_ce_rfc3986_uri_type; zend_class_entry *php_uri_ce_rfc3986_uri_host_type; zend_class_entry *php_uri_ce_whatwg_url; +zend_class_entry *php_uri_ce_whatwg_url_percent_encoding_mode; zend_class_entry *php_uri_ce_comparison_mode; zend_class_entry *php_uri_ce_exception; zend_class_entry *php_uri_ce_error; @@ -1065,6 +1066,59 @@ PHP_METHOD(Uri_WhatWg_Url, __debugInfo) RETURN_ARR(uri_get_debug_properties(uri_object)); } +PHP_FUNCTION(Uri_WhatWg_url_percent_encode) +{ + zend_string *input; + zend_enum_Uri_WhatWg_UrlPercentEncodingMode mode; + + ZEND_PARSE_PARAMETERS_START(2, 2) + Z_PARAM_STR(input) + Z_PARAM_ENUM(mode, php_uri_ce_whatwg_url_percent_encoding_mode) + ZEND_PARSE_PARAMETERS_END(); + + zend_string *str; + + switch (mode) { + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Username: + ZEND_FALLTHROUGH; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Password: + str = php_uri_parser_whatwg_percent_encode_userinfo_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaqueHost: + str = php_uri_parser_whatwg_percent_encode_opaque_host_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Path: + str = php_uri_parser_whatwg_percent_encode_path_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaquePath: + str = php_uri_parser_whatwg_percent_encode_opaque_path_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_PathSegment: + str = php_uri_parser_whatwg_percent_encode_path_segment_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Query: + str = php_uri_parser_whatwg_percent_encode_query_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_SpecialQuery: + str = php_uri_parser_whatwg_percent_encode_special_query_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_FormQuery: + str = php_uri_parser_whatwg_percent_encode_form_query_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + case ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Fragment: + str = php_uri_parser_whatwg_percent_encode_fragment_component(ZSTR_VAL(input), ZSTR_LEN(input)); + break; + default: ZEND_UNREACHABLE(); + } + + if (str == NULL) { + zend_throw_exception(php_uri_ce_error, "Cannot percent-encode input", 0); + RETURN_THROWS(); + } + + RETURN_NEW_STR(str); +} + PHP_METHOD(Uri_Rfc3986_UriBuilder, reset) { ZEND_PARSE_PARAMETERS_NONE(); @@ -1335,6 +1389,8 @@ static PHP_MINIT_FUNCTION(uri) object_handlers_whatwg_uri.free_obj = php_uri_object_handler_free; object_handlers_whatwg_uri.clone_obj = php_uri_object_handler_clone; + php_uri_ce_whatwg_url_percent_encoding_mode = register_class_Uri_WhatWg_UrlPercentEncodingMode(); + php_uri_ce_comparison_mode = register_class_Uri_UriComparisonMode(); php_uri_ce_exception = register_class_Uri_UriException(zend_ce_exception); php_uri_ce_error = register_class_Uri_UriError(zend_ce_error); @@ -1403,7 +1459,7 @@ zend_module_entry uri_module_entry = { STANDARD_MODULE_HEADER_EX, NULL, uri_deps, "uri", /* Extension name */ - NULL, /* zend_function_entry */ + ext_functions, /* zend_function_entry */ PHP_MINIT(uri), /* PHP_MINIT - Module initialization */ PHP_MSHUTDOWN(uri), /* PHP_MSHUTDOWN - Module shutdown */ PHP_RINIT(uri), /* PHP_RINIT - Request initialization */ diff --git a/ext/uri/php_uri.stub.php b/ext/uri/php_uri.stub.php index 81a766c0e16d..75d7118e875f 100644 --- a/ext/uri/php_uri.stub.php +++ b/ext/uri/php_uri.stub.php @@ -284,4 +284,20 @@ public function __unserialize(array $data): void {} public function __debugInfo(): array {} } + + enum UrlPercentEncodingMode + { + case Username; + case Password; + case OpaqueHost; + case Path; + case OpaquePath; + case PathSegment; + case Query; + case SpecialQuery; + case FormQuery; + case Fragment; + } + + function url_percent_encode(string $input, \Uri\WhatWg\UrlPercentEncodingMode $mode): string {} } diff --git a/ext/uri/php_uri_arginfo.h b/ext/uri/php_uri_arginfo.h index 1231408fbeb6..5f429f6549ad 100644 --- a/ext/uri/php_uri_arginfo.h +++ b/ext/uri/php_uri_arginfo.h @@ -1,7 +1,12 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: bfd9247fa79baf877d600134c9ef615ec5ca9cea + * Stub hash: d78664a7710d76025170fb4ab053f6b991d9ede4 * Has decl header: yes */ +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_Uri_WhatWg_url_percent_encode, 0, 2, IS_STRING, 0) + ZEND_ARG_TYPE_INFO(0, input, IS_STRING, 0) + ZEND_ARG_OBJ_INFO(0, mode, Uri\\WhatWg\\\125rlPercentEncodingMode, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Uri_Rfc3986_UriBuilder_reset, 0, 0, IS_STATIC, 0) ZEND_END_ARG_INFO() @@ -219,6 +224,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_Uri_WhatWg_Url___debugInfo arginfo_class_Uri_Rfc3986_Uri___serialize +ZEND_FUNCTION(Uri_WhatWg_url_percent_encode); ZEND_METHOD(Uri_Rfc3986_UriBuilder, reset); ZEND_METHOD(Uri_Rfc3986_UriBuilder, setScheme); ZEND_METHOD(Uri_Rfc3986_UriBuilder, setUserInfo); @@ -283,6 +289,11 @@ ZEND_METHOD(Uri_WhatWg_Url, __serialize); ZEND_METHOD(Uri_WhatWg_Url, __unserialize); ZEND_METHOD(Uri_WhatWg_Url, __debugInfo); +static const zend_function_entry ext_functions[] = { + ZEND_RAW_FENTRY(ZEND_NS_NAME("Uri\\WhatWg", "url_percent_encode"), zif_Uri_WhatWg_url_percent_encode, arginfo_Uri_WhatWg_url_percent_encode, 0, NULL, NULL) + ZEND_FE_END +}; + static const zend_function_entry class_Uri_Rfc3986_UriBuilder_methods[] = { ZEND_ME(Uri_Rfc3986_UriBuilder, reset, arginfo_class_Uri_Rfc3986_UriBuilder_reset, ZEND_ACC_PUBLIC) ZEND_ME(Uri_Rfc3986_UriBuilder, setScheme, arginfo_class_Uri_Rfc3986_UriBuilder_setScheme, ZEND_ACC_PUBLIC) @@ -641,3 +652,30 @@ static zend_class_entry *register_class_Uri_WhatWg_Url(void) return class_entry; } + +static zend_class_entry *register_class_Uri_WhatWg_UrlPercentEncodingMode(void) +{ + zend_class_entry *class_entry = zend_register_internal_enum("Uri\\WhatWg\\UrlPercentEncodingMode", IS_UNDEF, NULL); + + zend_enum_add_case_cstr(class_entry, "Username", NULL); + + zend_enum_add_case_cstr(class_entry, "Password", NULL); + + zend_enum_add_case_cstr(class_entry, "OpaqueHost", NULL); + + zend_enum_add_case_cstr(class_entry, "Path", NULL); + + zend_enum_add_case_cstr(class_entry, "OpaquePath", NULL); + + zend_enum_add_case_cstr(class_entry, "PathSegment", NULL); + + zend_enum_add_case_cstr(class_entry, "Query", NULL); + + zend_enum_add_case_cstr(class_entry, "SpecialQuery", NULL); + + zend_enum_add_case_cstr(class_entry, "FormQuery", NULL); + + zend_enum_add_case_cstr(class_entry, "Fragment", NULL); + + return class_entry; +} diff --git a/ext/uri/php_uri_common.h b/ext/uri/php_uri_common.h index 9106f6acd15f..8c8dfd621aec 100644 --- a/ext/uri/php_uri_common.h +++ b/ext/uri/php_uri_common.h @@ -22,6 +22,7 @@ extern zend_class_entry *php_uri_ce_rfc3986_uri; extern zend_class_entry *php_uri_ce_rfc3986_uri_type; extern zend_class_entry *php_uri_ce_rfc3986_uri_host_type; extern zend_class_entry *php_uri_ce_whatwg_url; +extern zend_class_entry *php_uri_ce_whatwg_url_percent_encoding_mode; extern zend_class_entry *php_uri_ce_comparison_mode; extern zend_class_entry *php_uri_ce_exception; extern zend_class_entry *php_uri_ce_error; diff --git a/ext/uri/php_uri_decl.h b/ext/uri/php_uri_decl.h index 9c817659cf76..4e751f08713c 100644 --- a/ext/uri/php_uri_decl.h +++ b/ext/uri/php_uri_decl.h @@ -1,8 +1,8 @@ /* This is a generated file, edit php_uri.stub.php instead. - * Stub hash: bfd9247fa79baf877d600134c9ef615ec5ca9cea */ + * Stub hash: d78664a7710d76025170fb4ab053f6b991d9ede4 */ -#ifndef ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H -#define ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H +#ifndef ZEND_PHP_URI_DECL_d78664a7710d76025170fb4ab053f6b991d9ede4_H +#define ZEND_PHP_URI_DECL_d78664a7710d76025170fb4ab053f6b991d9ede4_H typedef enum zend_enum_Uri_UriComparisonMode { ZEND_ENUM_Uri_UriComparisonMode_IncludeFragment = 1, @@ -63,4 +63,17 @@ typedef enum zend_enum_Uri_WhatWg_UrlHostType { ZEND_ENUM_Uri_WhatWg_UrlHostType_Empty = 5, } zend_enum_Uri_WhatWg_UrlHostType; -#endif /* ZEND_PHP_URI_DECL_bfd9247fa79baf877d600134c9ef615ec5ca9cea_H */ +typedef enum zend_enum_Uri_WhatWg_UrlPercentEncodingMode { + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Username = 1, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Password = 2, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaqueHost = 3, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Path = 4, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_OpaquePath = 5, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_PathSegment = 6, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Query = 7, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_SpecialQuery = 8, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_FormQuery = 9, + ZEND_ENUM_Uri_WhatWg_UrlPercentEncodingMode_Fragment = 10, +} zend_enum_Uri_WhatWg_UrlPercentEncodingMode; + +#endif /* ZEND_PHP_URI_DECL_d78664a7710d76025170fb4ab053f6b991d9ede4_H */ diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_control.phpt new file mode 100644 index 000000000000..a5dd0ce69038 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_percent.phpt new file mode 100644 index 000000000000..238f1b0b01f7 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_space.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_space.phpt new file mode 100644 index 000000000000..50d649454213 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_space.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - space code point +--FILE-- + +--EXPECT-- +string(10) "WHATWG+url" diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_in_set.phpt new file mode 100644 index 000000000000..82f622575917 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - special code points in the percent-encode set +--FILE-- +&+,', Uri\WhatWg\UrlPercentEncodingMode::FormQuery)); + +?> +--EXPECT-- +string(21) "%22%23%3C%3E%26%2B%2C" diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_not_in_set.phpt new file mode 100644 index 000000000000..590f6dd31023 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(4) "*-._" diff --git a/ext/uri/tests/whatwg/percent_encoding/form_query_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/form_query_success_unicode.phpt new file mode 100644 index 000000000000..bcb843ca67a6 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/form_query_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - form query - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/fragment_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/fragment_success_control.phpt new file mode 100644 index 000000000000..c0992a9e260f --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/fragment_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - fragment - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/fragment_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/fragment_success_percent.phpt new file mode 100644 index 000000000000..12b2bada8fae --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/fragment_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - fragment - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_in_set.phpt new file mode 100644 index 000000000000..fe129d66895f --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - fragment - special code points in the percent-encode set +--FILE-- +`', Uri\WhatWg\UrlPercentEncodingMode::Fragment)); + +?> +--EXPECT-- +string(15) "%20%22%3C%3E%60" diff --git a/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_not_in_set.phpt new file mode 100644 index 000000000000..255c5173ef83 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/fragment_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - fragment - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "('$+)" diff --git a/ext/uri/tests/whatwg/percent_encoding/fragment_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/fragment_success_unicode.phpt new file mode 100644 index 000000000000..0a14a113f386 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/fragment_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - fragment - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_control.phpt new file mode 100644 index 000000000000..7adc5b963787 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque host - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_percent.phpt new file mode 100644 index 000000000000..f6c6d12e4c7b --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque host - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_special_not_in_set.phpt new file mode 100644 index 000000000000..a170079625f9 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque host - special code points not in the percent-encode set +--FILE-- +?^`{}@'$+,", Uri\WhatWg\UrlPercentEncodingMode::OpaqueHost)); + +?> +--EXPECT-- +string(15) " "#<>?^`{}@'$+," diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_unicode.phpt new file mode 100644 index 000000000000..b51ad97b54dc --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_host_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque host - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_control.phpt new file mode 100644 index 000000000000..adf1bee19b6c --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque path - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_percent.phpt new file mode 100644 index 000000000000..7fa6a7c3973f --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque path - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_special_not_in_set.phpt new file mode 100644 index 000000000000..fa9075856a5c --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque path - special code points not in the percent-encode set +--FILE-- +?^`{}@'$+,", Uri\WhatWg\UrlPercentEncodingMode::OpaquePath)); + +?> +--EXPECT-- +string(15) " "#<>?^`{}@'$+," diff --git a/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_unicode.phpt new file mode 100644 index 000000000000..3fbae7c2c156 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/opaque_path_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - opaque path - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_segment_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/password_segment_success_control.phpt new file mode 100644 index 000000000000..db817d7b7146 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_segment_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/password_success_control.phpt new file mode 100644 index 000000000000..57ff019878df --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/password_success_percent.phpt new file mode 100644 index 000000000000..536a2702a428 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/password_success_special_in_set.phpt new file mode 100644 index 000000000000..f4041e059e88 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - special code points in the percent-encode set +--FILE-- + +--EXPECT-- +string(21) "%5B%23%3D%3F%20%60%5D" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/password_success_special_not_in_set.phpt new file mode 100644 index 000000000000..a4a151c44487 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "('$+)" diff --git a/ext/uri/tests/whatwg/percent_encoding/password_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/password_success_unicode.phpt new file mode 100644 index 000000000000..d2d0247f98f3 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/password_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - password - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_segment_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_control.phpt new file mode 100644 index 000000000000..0c9bfcbb0b1e --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path segment - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_segment_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_percent.phpt new file mode 100644 index 000000000000..258cca36a2ee --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path segment - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_in_set.phpt new file mode 100644 index 000000000000..03f43a8a0405 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path segment - special code points in the percent-encode set +--FILE-- +?^`{}/', Uri\WhatWg\UrlPercentEncodingMode::PathSegment)); + +?> +--EXPECT-- +string(33) "%20%22%23%3C%3E%3F%5E%60%7B%7D%2F" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_not_in_set.phpt new file mode 100644 index 000000000000..50790f66eb6c --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path segment - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "@'$+," diff --git a/ext/uri/tests/whatwg/percent_encoding/path_segment_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_unicode.phpt new file mode 100644 index 000000000000..218d120ae9ea --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_segment_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path segment - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/path_success_control.phpt new file mode 100644 index 000000000000..fa56acc3a3c5 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/path_success_percent.phpt new file mode 100644 index 000000000000..013c9e770740 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/path_success_special_in_set.phpt new file mode 100644 index 000000000000..785c82902620 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path - special code points in the percent-encode set +--FILE-- +?^`{}', Uri\WhatWg\UrlPercentEncodingMode::Path)); + +?> +--EXPECT-- +string(30) "%20%22%23%3C%3E%3F%5E%60%7B%7D" diff --git a/ext/uri/tests/whatwg/percent_encoding/path_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/path_success_special_not_in_set.phpt new file mode 100644 index 000000000000..17f6bf915407 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "@'$+," diff --git a/ext/uri/tests/whatwg/percent_encoding/path_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/path_success_unicode.phpt new file mode 100644 index 000000000000..edfa72359251 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/path_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - path - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_control.phpt new file mode 100644 index 000000000000..2502cc7a662c --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_percent.phpt new file mode 100644 index 000000000000..e9a4187b963d --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_space.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_space.phpt new file mode 100644 index 000000000000..b9a491018580 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_space.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - space code point +--FILE-- + +--EXPECT-- +string(12) "WHATWG%20url" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_special_in_set.phpt new file mode 100644 index 000000000000..a5fab6b7cd08 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - special code points in the percent-encode set +--FILE-- +', Uri\WhatWg\UrlPercentEncodingMode::Query)); + +?> +--EXPECT-- +string(15) "%20%22%23%3C%3E" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_special_not_in_set.phpt new file mode 100644 index 000000000000..c8e4123d93ff --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(6) "[@?&]'" diff --git a/ext/uri/tests/whatwg/percent_encoding/query_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/query_success_unicode.phpt new file mode 100644 index 000000000000..f5b3988f08fe --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/query_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - query - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_control.phpt new file mode 100644 index 000000000000..f6d76153043f --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_percent.phpt new file mode 100644 index 000000000000..a1683a1ef77b --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_space.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_space.phpt new file mode 100644 index 000000000000..049a5da1d4ed --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_space.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - space code point +--FILE-- + +--EXPECT-- +string(12) "WHATWG%20url" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_in_set.phpt new file mode 100644 index 000000000000..e84df8465c9f --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - special code points in the percent-encode set +--FILE-- +", Uri\WhatWg\UrlPercentEncodingMode::SpecialQuery)); + +?> +--EXPECT-- +string(18) "%20%27%22%23%3C%3E" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_not_in_set.phpt new file mode 100644 index 000000000000..0ee677b31fe1 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "[@?&]" diff --git a/ext/uri/tests/whatwg/percent_encoding/special_query_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/special_query_success_unicode.phpt new file mode 100644 index 000000000000..b583d8de2ecc --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/special_query_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - special query - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/tests/whatwg/percent_encoding/username_success_control.phpt b/ext/uri/tests/whatwg/percent_encoding/username_success_control.phpt new file mode 100644 index 000000000000..5a64393065c9 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/username_success_control.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - username - control code points +--FILE-- + +--EXPECT-- +string(3) "%11" diff --git a/ext/uri/tests/whatwg/percent_encoding/username_success_percent.phpt b/ext/uri/tests/whatwg/percent_encoding/username_success_percent.phpt new file mode 100644 index 000000000000..9ea2831efa46 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/username_success_percent.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - username - percent sign code point +--FILE-- + +--EXPECT-- +string(14) "WHATWG%2520url" diff --git a/ext/uri/tests/whatwg/percent_encoding/username_success_special_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/username_success_special_in_set.phpt new file mode 100644 index 000000000000..070250ef3630 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/username_success_special_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - username - special code points in the percent-encode set +--FILE-- + +--EXPECT-- +string(21) "%5B%23%3D%3F%20%60%5D" diff --git a/ext/uri/tests/whatwg/percent_encoding/username_success_special_not_in_set.phpt b/ext/uri/tests/whatwg/percent_encoding/username_success_special_not_in_set.phpt new file mode 100644 index 000000000000..8626b96ab9b3 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/username_success_special_not_in_set.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - username - special code points not in the percent-encode set +--FILE-- + +--EXPECT-- +string(5) "('$+)" diff --git a/ext/uri/tests/whatwg/percent_encoding/username_success_unicode.phpt b/ext/uri/tests/whatwg/percent_encoding/username_success_unicode.phpt new file mode 100644 index 000000000000..d85b0712c1f0 --- /dev/null +++ b/ext/uri/tests/whatwg/percent_encoding/username_success_unicode.phpt @@ -0,0 +1,10 @@ +--TEST-- +Test Uri\WhatWg\url_percent_encode() - username - Unicode code points +--FILE-- + +--EXPECT-- +string(13) "f%C3%B6%C5%91" diff --git a/ext/uri/uri_parser_whatwg.c b/ext/uri/uri_parser_whatwg.c index 6d46feb51aae..1626c97e09d8 100644 --- a/ext/uri/uri_parser_whatwg.c +++ b/ext/uri/uri_parser_whatwg.c @@ -25,6 +25,7 @@ ZEND_TLS lexbor_mraw_t lexbor_mraw = {0}; ZEND_TLS lxb_url_parser_t lexbor_parser = {0}; ZEND_TLS lxb_unicode_idna_t lexbor_idna = {0}; +ZEND_TLS uint8_t lexbor_custom_url_map[256]; static const size_t lexbor_mraw_byte_size = 8192; @@ -53,6 +54,11 @@ static zend_always_inline void zval_long_or_null_to_lexbor_str(const zval *value } } +ZEND_ATTRIBUTE_NONNULL static zend_always_inline zend_string *lexbor_str_to_zend_string(const lexbor_str_t *lexbor_str) +{ + return zend_string_init((const char *) lexbor_str->data, lexbor_str->length, 0); +} + /** * Creates a Uri\WhatWg\UrlValidationError class by mapping error codes listed in * https://url.spec.whatwg.org/#writing to a Uri\WhatWg\UrlValidationErrorType enum. @@ -578,6 +584,9 @@ PHP_RINIT_FUNCTION(uri_parser_whatwg) goto fail; } + memcpy(lexbor_custom_url_map, lxb_url_map, sizeof(lxb_url_map)); + lexbor_custom_url_map[37] = -1; /* % is percent-encoded */ + return SUCCESS; fail: @@ -665,6 +674,146 @@ static zend_string *php_uri_parser_whatwg_to_string(void *uri, const php_uri_rec return smart_str_extract(&uri_str); } +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_userinfo_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_USERINFO, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_opaque_host_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_C0, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_path_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_PATH, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_opaque_path_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_C0, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_path_segment_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + lexbor_custom_url_map[47] |= LXB_URL_MAP_PATH; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_PATH, false, lexbor_custom_url_map + ); + + lexbor_custom_url_map[47] &= ~LXB_URL_MAP_PATH; + + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_query_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_QUERY, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_special_query_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_SPECIAL_QUERY, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_form_query_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_X_WWW_FORM, true, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_fragment_component(const char *str, const size_t str_length) +{ + lexbor_str_t lexbor_str = {0}; + + const lexbor_status_t status = lxb_url_percent_encode_after_utf_8_ex( + (lxb_char_t *) str, (lxb_char_t *) str + str_length, &lexbor_str, lexbor_parser.mraw, LXB_URL_MAP_FRAGMENT, false, lexbor_custom_url_map + ); + if (status != LXB_STATUS_OK) { + lexbor_str_destroy(&lexbor_str, lexbor_parser.mraw, false); + return NULL; + } + + return lexbor_str_to_zend_string(&lexbor_str); +} + static void php_uri_parser_whatwg_destroy(void *uri) { lxb_url_t *lexbor_uri = uri; diff --git a/ext/uri/uri_parser_whatwg.h b/ext/uri/uri_parser_whatwg.h index f714ee483680..d3929c91cae6 100644 --- a/ext/uri/uri_parser_whatwg.h +++ b/ext/uri/uri_parser_whatwg.h @@ -25,6 +25,16 @@ ZEND_ATTRIBUTE_NONNULL void php_uri_parser_whatwg_host_type_read(const lxb_url_t lxb_url_t *php_uri_parser_whatwg_parse_ex(const char *uri_str, size_t uri_str_len, const lxb_url_t *lexbor_base_url, zval *errors, bool silent); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_userinfo_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_opaque_host_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_path_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_opaque_path_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_path_segment_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_query_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_special_query_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_form_query_component(const char *str, size_t str_length); +ZEND_ATTRIBUTE_NONNULL zend_string *php_uri_parser_whatwg_percent_encode_fragment_component(const char *str, size_t str_length); + PHP_RINIT_FUNCTION(uri_parser_whatwg); ZEND_MODULE_POST_ZEND_DEACTIVATE_D(uri_parser_whatwg);