From 992e5a76d11675a4bb919f9bcf1c1a3b215d66d5 Mon Sep 17 00:00:00 2001 From: lamentxu <1372449351@qq.com> Date: Fri, 27 Mar 2026 18:23:37 +0800 Subject: [PATCH 1/7] Update uri_parser_rfc3986.c --- ext/uri/uri_parser_rfc3986.c | 45 +++++++++++++++++++++++++++--------- 1 file changed, 34 insertions(+), 11 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index a047c63a708dd..ba6598f38bca4 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -237,13 +237,15 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void if (has_text_range(&uriparser_uri->hostText)) { if (uriparser_uri->hostData.ip6 != NULL || uriparser_uri->hostData.ipFuture.first != NULL) { /* the textual representation of the host is always accessible in the .hostText field no matter what the host is */ - smart_str host_str = {0}; + const size_t host_len = get_text_range_length(&uriparser_uri->hostText); + zend_string *host_str = zend_string_alloc(host_len + 2, false); - smart_str_appendc(&host_str, '['); - smart_str_appendl(&host_str, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); - smart_str_appendc(&host_str, ']'); + ZSTR_VAL(host_str)[0] = '['; + memcpy(ZSTR_VAL(host_str) + 1, uriparser_uri->hostText.first, host_len); + ZSTR_VAL(host_str)[host_len + 1] = ']'; + ZSTR_VAL(host_str)[host_len + 2] = '\0'; - ZVAL_NEW_STR(retval, smart_str_extract(&host_str)); + ZVAL_STR(retval, host_str); } else { ZVAL_STRINGL(retval, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); } @@ -349,20 +351,41 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void const UriUriA *uriparser_uri = get_uri_for_reading(uri, read_mode); if (uriparser_uri->pathHead != NULL) { - smart_str str = {0}; + size_t total_len = 0; + const bool need_leading_slash = uriparser_uri->absolutePath || uriHasHostA(uriparser_uri); - if (uriparser_uri->absolutePath || uriHasHostA(uriparser_uri)) { - smart_str_appendc(&str, '/'); + if (need_leading_slash) { + total_len++; } for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { - smart_str_appendl(&str, p->text.first, get_text_range_length(&p->text)); + total_len += get_text_range_length(&p->text); if (p->next) { - smart_str_appendc(&str, '/'); + total_len++; } } - ZVAL_NEW_STR(retval, smart_str_extract(&str)); + zend_string *str = zend_string_alloc(total_len, false); + char *out = ZSTR_VAL(str); + size_t pos = 0; + + if (need_leading_slash) { + out[pos++] = '/'; + } + + for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { + const size_t len = get_text_range_length(&p->text); + if (len > 0) { + memcpy(out + pos, p->text.first, len); + pos += len; + } + if (p->next) { + out[pos++] = '/'; + } + } + + out[total_len] = '\0'; + ZVAL_STR(retval, str); } else if (uriparser_uri->absolutePath) { ZVAL_CHAR(retval, '/'); } else { From b8b4a7c894b73ac9e0f9197e53c5de7a0a0c5399 Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Fri, 27 Mar 2026 22:32:42 +0800 Subject: [PATCH 2/7] Apply code review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tim Düsterhus --- ext/uri/uri_parser_rfc3986.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index ba6598f38bca4..853ec5be65d16 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -367,24 +367,19 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void zend_string *str = zend_string_alloc(total_len, false); char *out = ZSTR_VAL(str); - size_t pos = 0; if (need_leading_slash) { - out[pos++] = '/'; + *(out++) = '/'; } for (const UriPathSegmentA *p = uriparser_uri->pathHead; p; p = p->next) { - const size_t len = get_text_range_length(&p->text); - if (len > 0) { - memcpy(out + pos, p->text.first, len); - pos += len; - } + out = zend_mempcpy(out, p->text.first, get_text_range_length(&p->text)); if (p->next) { - out[pos++] = '/'; + *(out++) = '/'; } } - out[total_len] = '\0'; + *out = '\0'; ZVAL_STR(retval, str); } else if (uriparser_uri->absolutePath) { ZVAL_CHAR(retval, '/'); From ba2a1f539c7eb0c55d1124dca534219bb226b1a5 Mon Sep 17 00:00:00 2001 From: lamentxu <1372449351@qq.com> Date: Fri, 27 Mar 2026 22:41:09 +0800 Subject: [PATCH 3/7] use pointer arithmetic --- ext/uri/uri_parser_rfc3986.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index ba6598f38bca4..44317c2d3c643 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -240,10 +240,12 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void const size_t host_len = get_text_range_length(&uriparser_uri->hostText); zend_string *host_str = zend_string_alloc(host_len + 2, false); - ZSTR_VAL(host_str)[0] = '['; - memcpy(ZSTR_VAL(host_str) + 1, uriparser_uri->hostText.first, host_len); - ZSTR_VAL(host_str)[host_len + 1] = ']'; - ZSTR_VAL(host_str)[host_len + 2] = '\0'; + char *out = ZSTR_VAL(host_str); + + *(out++) = '['; + out = zend_mempcpy(out, uriparser_uri->hostText.first, host_len); + *(out++) = ']'; + *out = '\0'; ZVAL_STR(retval, host_str); } else { From 84f7b2c41bd9b55f13712e47f87156373d6c7221 Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Fri, 27 Mar 2026 22:42:12 +0800 Subject: [PATCH 4/7] use ZVAL_NEW_STR instead of ZVAL_STR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tim Düsterhus --- ext/uri/uri_parser_rfc3986.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index c23c3a39317bf..29fc56aa245a2 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -247,7 +247,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void *(out++) = ']'; *out = '\0'; - ZVAL_STR(retval, host_str); + ZVAL_NEW_STR(retval, host_str); } else { ZVAL_STRINGL(retval, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); } @@ -382,7 +382,7 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void } *out = '\0'; - ZVAL_STR(retval, str); + ZVAL_NEW_STR(retval, str); } else if (uriparser_uri->absolutePath) { ZVAL_CHAR(retval, '/'); } else { From f7eeb4c3b24b9c3d8cb043b9f537ba614dd38699 Mon Sep 17 00:00:00 2001 From: lamentxu <1372449351@qq.com> Date: Fri, 27 Mar 2026 22:46:49 +0800 Subject: [PATCH 5/7] Update UPGRADING --- UPGRADING | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UPGRADING b/UPGRADING index e55b9730f71a4..8c312f1814a02 100644 --- a/UPGRADING +++ b/UPGRADING @@ -264,5 +264,8 @@ PHP 8.6 UPGRADE NOTES . Improved performance of intval('+0b...', 2) and intval('0b...', 2). . Improved performance of str_split(). +- URI: + . Reduced allocations when reading RFC3986 IPv6/IPFuture hosts and paths. + - Zip: . Avoid string copies in ZipArchive::addFromString(). From 75dcdad464d207e8310f69f70991f613231b93f4 Mon Sep 17 00:00:00 2001 From: lamentxu <1372449351@qq.com> Date: Sat, 28 Mar 2026 00:55:11 +0800 Subject: [PATCH 6/7] use zend_string_concat3 --- ext/uri/uri_parser_rfc3986.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index 29fc56aa245a2..e326cc72d3b71 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -238,15 +238,12 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void if (uriparser_uri->hostData.ip6 != NULL || uriparser_uri->hostData.ipFuture.first != NULL) { /* the textual representation of the host is always accessible in the .hostText field no matter what the host is */ const size_t host_len = get_text_range_length(&uriparser_uri->hostText); - zend_string *host_str = zend_string_alloc(host_len + 2, false); - - char *out = ZSTR_VAL(host_str); - - *(out++) = '['; - out = zend_mempcpy(out, uriparser_uri->hostText.first, host_len); - *(out++) = ']'; - *out = '\0'; - + + zend_string *host_str = zend_string_concat3( + "[", 1, + uriparser_uri->hostText.first, host_len, + "]", 1 + ); ZVAL_NEW_STR(retval, host_str); } else { ZVAL_STRINGL(retval, uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText)); From 9e763f328ccdc8f97621638d86222719a6636998 Mon Sep 17 00:00:00 2001 From: Weilin Du <108666168+LamentXU123@users.noreply.github.com> Date: Sat, 28 Mar 2026 01:02:39 +0800 Subject: [PATCH 7/7] Update ext/uri/uri_parser_rfc3986.c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Tim Düsterhus --- ext/uri/uri_parser_rfc3986.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/uri/uri_parser_rfc3986.c b/ext/uri/uri_parser_rfc3986.c index e326cc72d3b71..5f1edbefe2bbc 100644 --- a/ext/uri/uri_parser_rfc3986.c +++ b/ext/uri/uri_parser_rfc3986.c @@ -237,11 +237,9 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void if (has_text_range(&uriparser_uri->hostText)) { if (uriparser_uri->hostData.ip6 != NULL || uriparser_uri->hostData.ipFuture.first != NULL) { /* the textual representation of the host is always accessible in the .hostText field no matter what the host is */ - const size_t host_len = get_text_range_length(&uriparser_uri->hostText); - zend_string *host_str = zend_string_concat3( "[", 1, - uriparser_uri->hostText.first, host_len, + uriparser_uri->hostText.first, get_text_range_length(&uriparser_uri->hostText), "]", 1 ); ZVAL_NEW_STR(retval, host_str);