@@ -237,13 +237,12 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_host_read(void
237237 if (has_text_range (& uriparser_uri -> hostText )) {
238238 if (uriparser_uri -> hostData .ip6 != NULL || uriparser_uri -> hostData .ipFuture .first != NULL ) {
239239 /* the textual representation of the host is always accessible in the .hostText field no matter what the host is */
240- smart_str host_str = {0 };
241-
242- smart_str_appendc (& host_str , '[' );
243- smart_str_appendl (& host_str , uriparser_uri -> hostText .first , get_text_range_length (& uriparser_uri -> hostText ));
244- smart_str_appendc (& host_str , ']' );
245-
246- ZVAL_NEW_STR (retval , smart_str_extract (& host_str ));
240+ zend_string * host_str = zend_string_concat3 (
241+ "[" , 1 ,
242+ uriparser_uri -> hostText .first , get_text_range_length (& uriparser_uri -> hostText ),
243+ "]" , 1
244+ );
245+ ZVAL_NEW_STR (retval , host_str );
247246 } else {
248247 ZVAL_STRINGL (retval , uriparser_uri -> hostText .first , get_text_range_length (& uriparser_uri -> hostText ));
249248 }
@@ -349,20 +348,36 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void
349348 const UriUriA * uriparser_uri = get_uri_for_reading (uri , read_mode );
350349
351350 if (uriparser_uri -> pathHead != NULL ) {
352- smart_str str = {0 };
351+ size_t total_len = 0 ;
352+ const bool need_leading_slash = uriparser_uri -> absolutePath || uriHasHostA (uriparser_uri );
353+
354+ if (need_leading_slash ) {
355+ total_len ++ ;
356+ }
357+
358+ for (const UriPathSegmentA * p = uriparser_uri -> pathHead ; p ; p = p -> next ) {
359+ total_len += get_text_range_length (& p -> text );
360+ if (p -> next ) {
361+ total_len ++ ;
362+ }
363+ }
364+
365+ zend_string * str = zend_string_alloc (total_len , false);
366+ char * out = ZSTR_VAL (str );
353367
354- if (uriparser_uri -> absolutePath || uriHasHostA ( uriparser_uri ) ) {
355- smart_str_appendc ( & str , '/' ) ;
368+ if (need_leading_slash ) {
369+ * ( out ++ ) = '/' ;
356370 }
357371
358372 for (const UriPathSegmentA * p = uriparser_uri -> pathHead ; p ; p = p -> next ) {
359- smart_str_appendl ( & str , p -> text .first , get_text_range_length (& p -> text ));
373+ out = zend_mempcpy ( out , p -> text .first , get_text_range_length (& p -> text ));
360374 if (p -> next ) {
361- smart_str_appendc ( & str , '/' ) ;
375+ * ( out ++ ) = '/' ;
362376 }
363377 }
364378
365- ZVAL_NEW_STR (retval , smart_str_extract (& str ));
379+ * out = '\0' ;
380+ ZVAL_NEW_STR (retval , str );
366381 } else if (uriparser_uri -> absolutePath ) {
367382 ZVAL_CHAR (retval , '/' );
368383 } else {
0 commit comments