@@ -28,16 +28,12 @@ static inline size_t get_text_range_length(const UriTextRangeA *range)
28
28
return range -> afterLast - range -> first ;
29
29
}
30
30
31
- static UriUriA * uriparser_copy_uri (UriUriA * uriparser_uri )
31
+ static void uriparser_copy_uri (UriUriA * new_uriparser_uri , UriUriA * uriparser_uri )
32
32
{
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 );
36
34
37
35
int result = uriCopyUriA (new_uriparser_uri , uriparser_uri );
38
36
ZEND_ASSERT (result == URI_SUCCESS && new_uriparser_uri != NULL );
39
-
40
- return new_uriparser_uri ;
41
37
}
42
38
43
39
static void uriparser_normalize_uri (UriUriA * uriparser_uri )
@@ -46,20 +42,26 @@ static void uriparser_normalize_uri(UriUriA *uriparser_uri)
46
42
ZEND_ASSERT (result == URI_SUCCESS );
47
43
}
48
44
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
+
49
54
static UriUriA * uriparser_read_uri (uriparser_uris_t * uriparser_uris , uri_component_read_mode_t read_mode )
50
55
{
51
56
switch (read_mode ) {
52
57
case URI_COMPONENT_READ_RAW :
53
- return uriparser_uris -> uri ;
58
+ return & uriparser_uris -> uri ;
54
59
case URI_COMPONENT_READ_NORMALIZED_ASCII :
55
60
ZEND_FALLTHROUGH ;
56
61
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 );
61
63
62
- return uriparser_uris -> normalized_uri ;
64
+ return & uriparser_uris -> normalized_uri ;
63
65
EMPTY_SWITCH_DEFAULT_CASE ()
64
66
}
65
67
}
@@ -283,62 +285,56 @@ PHP_MINIT_FUNCTION(uri_uriparser)
283
285
return SUCCESS ;
284
286
}
285
287
286
- static uriparser_uris_t * uriparser_create_uris (
287
- UriUriA * uri ,
288
- UriUriA * normalized_uri
289
- ) {
288
+ static uriparser_uris_t * uriparser_create_uris (void )
289
+ {
290
290
uriparser_uris_t * uriparser_uris = emalloc (sizeof (uriparser_uris_t ));
291
-
292
- uriparser_uris -> uri = uri ;
293
- uriparser_uris -> normalized_uri = normalized_uri ;
291
+ uriparser_uris -> normalized_uri_initialized = false;
294
292
295
293
return uriparser_uris ;
296
294
}
297
295
298
296
static void throw_invalid_uri_exception (void )
299
297
{
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 );
301
299
}
302
300
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
+
303
314
void * uriparser_parse_uri_ex (const zend_string * uri_str , const uriparser_uris_t * uriparser_base_urls , bool silent )
304
315
{
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 ();
314
317
315
- return NULL ;
316
- }
317
-
318
- uriMakeOwnerA (uriparser_uri );
319
318
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
+ } else {
321
+ UriUriA uri ;
322
322
323
- UriUriA * absolute_uri = emalloc ( sizeof ( UriUriA ) );
323
+ PARSE_URI ( & uri , uri_str , uriparser_uris , silent );
324
324
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 );
325
+ if (uriAddBaseUriA (& uriparser_uris -> uri , & uri , & uriparser_base_urls -> uri ) != URI_SUCCESS ) {
326
+ efree (uriparser_uris );
327
+ if (!silent ) {
328
+ throw_invalid_uri_exception ();
329
+ }
329
330
330
- if (!silent ) {
331
- throw_invalid_uri_exception ();
331
+ return NULL ;
332
332
}
333
-
334
- return NULL ;
335
333
}
336
334
337
- uriMakeOwnerA (absolute_uri );
338
- uriFreeUriMembersA (uriparser_uri );
339
- efree (uriparser_uri );
335
+ uriMakeOwnerA (& uriparser_uris -> uri );
340
336
341
- return uriparser_create_uris ( absolute_uri , NULL ) ;
337
+ return uriparser_uris ;
342
338
}
343
339
344
340
void * uriparser_parse_uri (const zend_string * uri_str , const void * base_url , zval * errors , bool silent )
@@ -354,10 +350,14 @@ static void *uriparser_clone_uri(void *uri)
354
350
{
355
351
uriparser_uris_t * uriparser_uris = (uriparser_uris_t * ) uri ;
356
352
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
- );
353
+ uriparser_uris_t * new_uriparser_uris = uriparser_create_uris ();
354
+ uriparser_copy_uri (& new_uriparser_uris -> uri , & uriparser_uris -> uri );
355
+ if (uriparser_uris -> normalized_uri_initialized ) {
356
+ uriparser_copy_uri (& new_uriparser_uris -> normalized_uri , & uriparser_uris -> normalized_uri );
357
+ new_uriparser_uris -> normalized_uri_initialized = true;
358
+ }
359
+
360
+ return new_uriparser_uris ;
361
361
}
362
362
363
363
static zend_string * uriparser_uri_to_string (void * uri , uri_recomposition_mode_t recomposition_mode , bool exclude_fragment )
@@ -366,13 +366,11 @@ static zend_string *uriparser_uri_to_string(void *uri, uri_recomposition_mode_t
366
366
UriUriA * uriparser_uri ;
367
367
368
368
if (recomposition_mode == URI_RECOMPOSITION_RAW_ASCII || recomposition_mode == URI_RECOMPOSITION_RAW_UNICODE ) {
369
- uriparser_uri = uriparser_uris -> uri ;
369
+ uriparser_uri = & uriparser_uris -> uri ;
370
370
} 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 ;
371
+ normalize_uri_if_needed (uriparser_uris );
372
+
373
+ uriparser_uri = & uriparser_uris -> normalized_uri ;
376
374
}
377
375
378
376
int charsRequired = 0 ;
@@ -399,18 +397,12 @@ static void uriparser_free_uri(void *uri)
399
397
{
400
398
uriparser_uris_t * uriparser_uris = (uriparser_uris_t * ) uri ;
401
399
402
- if (uriparser_uris -> uri != NULL ) {
403
- uriFreeUriMembersA (uriparser_uris -> uri );
404
- efree (uriparser_uris -> uri );
405
- uriparser_uris -> uri = NULL ;
406
- }
400
+ uriFreeUriMembersA (& uriparser_uris -> uri );
407
401
408
- if (uriparser_uris -> normalized_uri != NULL ) {
409
- ZEND_ASSERT (uriparser_uris -> normalized_uri -> owner );
402
+ if (uriparser_uris -> normalized_uri_initialized ) {
403
+ ZEND_ASSERT (uriparser_uris -> normalized_uri . owner );
410
404
411
- uriFreeUriMembersA (uriparser_uris -> normalized_uri );
412
- efree (uriparser_uris -> normalized_uri );
413
- uriparser_uris -> normalized_uri = NULL ;
405
+ uriFreeUriMembersA (& uriparser_uris -> normalized_uri );
414
406
}
415
407
416
408
efree (uriparser_uris );
0 commit comments