@@ -237,13 +237,15 @@ 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 };
240+ const size_t host_len = get_text_range_length (& uriparser_uri -> hostText );
241+ zend_string * host_str = zend_string_alloc (host_len + 2 , false);
241242
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 , ']' );
243+ ZSTR_VAL (host_str )[0 ] = '[' ;
244+ memcpy (ZSTR_VAL (host_str ) + 1 , uriparser_uri -> hostText .first , host_len );
245+ ZSTR_VAL (host_str )[host_len + 1 ] = ']' ;
246+ ZSTR_VAL (host_str )[host_len + 2 ] = '\0' ;
245247
246- ZVAL_NEW_STR (retval , smart_str_extract ( & host_str ) );
248+ ZVAL_STR (retval , host_str );
247249 } else {
248250 ZVAL_STRINGL (retval , uriparser_uri -> hostText .first , get_text_range_length (& uriparser_uri -> hostText ));
249251 }
@@ -349,20 +351,41 @@ ZEND_ATTRIBUTE_NONNULL static zend_result php_uri_parser_rfc3986_path_read(void
349351 const UriUriA * uriparser_uri = get_uri_for_reading (uri , read_mode );
350352
351353 if (uriparser_uri -> pathHead != NULL ) {
352- smart_str str = {0 };
354+ size_t total_len = 0 ;
355+ const bool need_leading_slash = uriparser_uri -> absolutePath || uriHasHostA (uriparser_uri );
353356
354- if (uriparser_uri -> absolutePath || uriHasHostA ( uriparser_uri ) ) {
355- smart_str_appendc ( & str , '/' ) ;
357+ if (need_leading_slash ) {
358+ total_len ++ ;
356359 }
357360
358361 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 ) );
362+ total_len += get_text_range_length (& p -> text );
360363 if (p -> next ) {
361- smart_str_appendc ( & str , '/' ) ;
364+ total_len ++ ;
362365 }
363366 }
364367
365- ZVAL_NEW_STR (retval , smart_str_extract (& str ));
368+ zend_string * str = zend_string_alloc (total_len , false);
369+ char * out = ZSTR_VAL (str );
370+ size_t pos = 0 ;
371+
372+ if (need_leading_slash ) {
373+ out [pos ++ ] = '/' ;
374+ }
375+
376+ for (const UriPathSegmentA * p = uriparser_uri -> pathHead ; p ; p = p -> next ) {
377+ const size_t len = get_text_range_length (& p -> text );
378+ if (len > 0 ) {
379+ memcpy (out + pos , p -> text .first , len );
380+ pos += len ;
381+ }
382+ if (p -> next ) {
383+ out [pos ++ ] = '/' ;
384+ }
385+ }
386+
387+ out [total_len ] = '\0' ;
388+ ZVAL_STR (retval , str );
366389 } else if (uriparser_uri -> absolutePath ) {
367390 ZVAL_CHAR (retval , '/' );
368391 } else {
0 commit comments