@@ -28,16 +28,12 @@ static inline size_t get_text_range_length(const UriTextRangeA *range)
2828 return range -> afterLast - range -> first ;
2929}
3030
31- static UriUriA * uriparser_copy_uri (UriUriA * uriparser_uri )
31+ static void uriparser_copy_uri (UriUriA * new_uriparser_uri , UriUriA * uriparser_uri )
3232{
33- ZEND_ASSERT (uriparser_uri != NULL );
34-
35- UriUriA * new_uriparser_uri = emalloc (sizeof (UriUriA ));
33+ ZEND_ASSERT (new_uriparser_uri != NULL && uriparser_uri != NULL );
3634
3735 int result = uriCopyUriA (new_uriparser_uri , uriparser_uri );
3836 ZEND_ASSERT (result == URI_SUCCESS && new_uriparser_uri != NULL );
39-
40- return new_uriparser_uri ;
4137}
4238
4339static void uriparser_normalize_uri (UriUriA * uriparser_uri )
@@ -46,20 +42,26 @@ static void uriparser_normalize_uri(UriUriA *uriparser_uri)
4642 ZEND_ASSERT (result == URI_SUCCESS );
4743}
4844
45+ static void normalize_uri_if_needed (uriparser_uris_t * uriparser_uris )
46+ {
47+ if (uriparser_uris -> normalized_uri_initialized == false) {
48+ uriparser_copy_uri (& uriparser_uris -> normalized_uri , & uriparser_uris -> uri );
49+ uriparser_normalize_uri (& uriparser_uris -> normalized_uri );
50+ uriparser_uris -> normalized_uri_initialized = true;
51+ }
52+ }
53+
4954static UriUriA * uriparser_read_uri (uriparser_uris_t * uriparser_uris , uri_component_read_mode_t read_mode )
5055{
5156 switch (read_mode ) {
5257 case URI_COMPONENT_READ_RAW :
53- return uriparser_uris -> uri ;
58+ return & uriparser_uris -> uri ;
5459 case URI_COMPONENT_READ_NORMALIZED_ASCII :
5560 ZEND_FALLTHROUGH ;
5661 case URI_COMPONENT_READ_NORMALIZED_UNICODE :
57- if (uriparser_uris -> normalized_uri == NULL ) {
58- uriparser_uris -> normalized_uri = uriparser_copy_uri (uriparser_uris -> uri );
59- uriparser_normalize_uri (uriparser_uris -> normalized_uri );
60- }
62+ normalize_uri_if_needed (uriparser_uris );
6163
62- return uriparser_uris -> normalized_uri ;
64+ return & uriparser_uris -> normalized_uri ;
6365 EMPTY_SWITCH_DEFAULT_CASE ()
6466 }
6567}
@@ -283,62 +285,58 @@ PHP_MINIT_FUNCTION(uri_uriparser)
283285 return SUCCESS ;
284286}
285287
286- static uriparser_uris_t * uriparser_create_uris (
287- UriUriA * uri ,
288- UriUriA * normalized_uri
289- ) {
290- uriparser_uris_t * uriparser_uris = emalloc (sizeof (uriparser_uris_t ));
291-
292- uriparser_uris -> uri = uri ;
293- uriparser_uris -> normalized_uri = normalized_uri ;
288+ static uriparser_uris_t * uriparser_create_uris (void )
289+ {
290+ uriparser_uris_t * uriparser_uris = emalloc (sizeof (* uriparser_uris ));
291+ uriparser_uris -> normalized_uri_initialized = false;
294292
295293 return uriparser_uris ;
296294}
297295
298296static void throw_invalid_uri_exception (void )
299297{
300- zend_throw_exception (uri_invalid_uri_exception_ce , "URI parsing failed " , 0 );
298+ zend_throw_exception (uri_invalid_uri_exception_ce , "The specified URI is malformed " , 0 );
301299}
302300
301+ #define PARSE_URI (dest_uri , uri_str , uriparser_uris , silent ) \
302+ do { \
303+ if (ZSTR_LEN(uri_str) == 0 || \
304+ uriParseSingleUriExA(dest_uri, ZSTR_VAL(uri_str), ZSTR_VAL(uri_str) + ZSTR_LEN(uri_str), NULL) != URI_SUCCESS \
305+ ) { \
306+ efree(uriparser_uris); \
307+ if (!silent) { \
308+ throw_invalid_uri_exception(); \
309+ } \
310+ return NULL; \
311+ } \
312+ } while (0)
313+
303314void * uriparser_parse_uri_ex (const zend_string * uri_str , const uriparser_uris_t * uriparser_base_urls , bool silent )
304315{
305- UriUriA * uriparser_uri = emalloc (sizeof (UriUriA ));
306-
307- if (ZSTR_LEN (uri_str ) == 0 ||
308- uriParseSingleUriExA (uriparser_uri , ZSTR_VAL (uri_str ), ZSTR_VAL (uri_str ) + ZSTR_LEN (uri_str ), NULL ) != URI_SUCCESS
309- ) {
310- efree (uriparser_uri );
311- if (!silent ) {
312- throw_invalid_uri_exception ();
313- }
316+ uriparser_uris_t * uriparser_uris = uriparser_create_uris ();
314317
315- return NULL ;
316- }
317-
318- uriMakeOwnerA (uriparser_uri );
319318 if (uriparser_base_urls == NULL ) {
320- return uriparser_create_uris (uriparser_uri , NULL );
321- }
319+ PARSE_URI (& uriparser_uris -> uri , uri_str , uriparser_uris , silent );
320+ uriMakeOwnerA (& uriparser_uris -> uri );
321+ } else {
322+ UriUriA uri ;
322323
323- UriUriA * absolute_uri = emalloc ( sizeof ( UriUriA ) );
324+ PARSE_URI ( & uri , uri_str , uriparser_uris , silent );
324325
325- if (uriAddBaseUriA (absolute_uri , uriparser_uri , uriparser_base_urls -> uri ) != URI_SUCCESS ) {
326- uriFreeUriMembersA (uriparser_uri );
327- efree (uriparser_uri );
328- efree (absolute_uri );
326+ if (uriAddBaseUriA (& uriparser_uris -> uri , & uri , & uriparser_base_urls -> uri ) != URI_SUCCESS ) {
327+ efree (uriparser_uris );
328+ if (!silent ) {
329+ throw_invalid_uri_exception ();
330+ }
329331
330- if (!silent ) {
331- throw_invalid_uri_exception ();
332+ return NULL ;
332333 }
333334
334- return NULL ;
335+ uriMakeOwnerA (& uriparser_uris -> uri );
336+ uriFreeUriMembersA (& uri );
335337 }
336338
337- uriMakeOwnerA (absolute_uri );
338- uriFreeUriMembersA (uriparser_uri );
339- efree (uriparser_uri );
340-
341- return uriparser_create_uris (absolute_uri , NULL );
339+ return uriparser_uris ;
342340}
343341
344342void * uriparser_parse_uri (const zend_string * uri_str , const void * base_url , zval * errors , bool silent )
@@ -354,10 +352,14 @@ static void *uriparser_clone_uri(void *uri)
354352{
355353 uriparser_uris_t * uriparser_uris = (uriparser_uris_t * ) uri ;
356354
357- return uriparser_create_uris (
358- uriparser_copy_uri (uriparser_uris -> uri ),
359- uriparser_uris -> normalized_uri != NULL ? uriparser_copy_uri (uriparser_uris -> normalized_uri ) : NULL
360- );
355+ uriparser_uris_t * new_uriparser_uris = uriparser_create_uris ();
356+ uriparser_copy_uri (& new_uriparser_uris -> uri , & uriparser_uris -> uri );
357+ if (uriparser_uris -> normalized_uri_initialized ) {
358+ uriparser_copy_uri (& new_uriparser_uris -> normalized_uri , & uriparser_uris -> normalized_uri );
359+ new_uriparser_uris -> normalized_uri_initialized = true;
360+ }
361+
362+ return new_uriparser_uris ;
361363}
362364
363365static zend_string * uriparser_uri_to_string (void * uri , uri_recomposition_mode_t recomposition_mode , bool exclude_fragment )
@@ -366,13 +368,11 @@ static zend_string *uriparser_uri_to_string(void *uri, uri_recomposition_mode_t
366368 UriUriA * uriparser_uri ;
367369
368370 if (recomposition_mode == URI_RECOMPOSITION_RAW_ASCII || recomposition_mode == URI_RECOMPOSITION_RAW_UNICODE ) {
369- uriparser_uri = uriparser_uris -> uri ;
371+ uriparser_uri = & uriparser_uris -> uri ;
370372 } else {
371- if (uriparser_uris -> normalized_uri == NULL ) {
372- uriparser_uris -> normalized_uri = uriparser_copy_uri (uriparser_uris -> uri );
373- uriparser_normalize_uri (uriparser_uris -> normalized_uri );
374- }
375- uriparser_uri = uriparser_uris -> normalized_uri ;
373+ normalize_uri_if_needed (uriparser_uris );
374+
375+ uriparser_uri = & uriparser_uris -> normalized_uri ;
376376 }
377377
378378 int charsRequired = 0 ;
@@ -399,18 +399,12 @@ static void uriparser_free_uri(void *uri)
399399{
400400 uriparser_uris_t * uriparser_uris = (uriparser_uris_t * ) uri ;
401401
402- if (uriparser_uris -> uri != NULL ) {
403- uriFreeUriMembersA (uriparser_uris -> uri );
404- efree (uriparser_uris -> uri );
405- uriparser_uris -> uri = NULL ;
406- }
402+ uriFreeUriMembersA (& uriparser_uris -> uri );
407403
408- if (uriparser_uris -> normalized_uri != NULL ) {
409- ZEND_ASSERT (uriparser_uris -> normalized_uri -> owner );
404+ if (uriparser_uris -> normalized_uri_initialized ) {
405+ ZEND_ASSERT (uriparser_uris -> normalized_uri . owner );
410406
411- uriFreeUriMembersA (uriparser_uris -> normalized_uri );
412- efree (uriparser_uris -> normalized_uri );
413- uriparser_uris -> normalized_uri = NULL ;
407+ uriFreeUriMembersA (& uriparser_uris -> normalized_uri );
414408 }
415409
416410 efree (uriparser_uris );
0 commit comments