Skip to content

Commit 9b63691

Browse files
committed
Allocate on stack
1 parent 6e27188 commit 9b63691

File tree

7 files changed

+67
-76
lines changed

7 files changed

+67
-76
lines changed

ext/uri/php_uriparser.c

Lines changed: 60 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -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

4339
static 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+
4954
static 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,56 @@ 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-
) {
288+
static uriparser_uris_t *uriparser_create_uris(void)
289+
{
290290
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;
294292

295293
return uriparser_uris;
296294
}
297295

298296
static 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+
303314
void *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+
} else {
321+
UriUriA uri;
322322

323-
UriUriA *absolute_uri = emalloc(sizeof(UriUriA));
323+
PARSE_URI(&uri, uri_str, uriparser_uris, silent);
324324

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+
}
329330

330-
if (!silent) {
331-
throw_invalid_uri_exception();
331+
return NULL;
332332
}
333-
334-
return NULL;
335333
}
336334

337-
uriMakeOwnerA(absolute_uri);
338-
uriFreeUriMembersA(uriparser_uri);
339-
efree(uriparser_uri);
335+
uriMakeOwnerA(&uriparser_uris->uri);
340336

341-
return uriparser_create_uris(absolute_uri, NULL);
337+
return uriparser_uris;
342338
}
343339

344340
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)
354350
{
355351
uriparser_uris_t *uriparser_uris = (uriparser_uris_t *) uri;
356352

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;
361361
}
362362

363363
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
366366
UriUriA *uriparser_uri;
367367

368368
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;
370370
} 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;
376374
}
377375

378376
int charsRequired = 0;
@@ -399,18 +397,12 @@ static void uriparser_free_uri(void *uri)
399397
{
400398
uriparser_uris_t *uriparser_uris = (uriparser_uris_t *) uri;
401399

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);
407401

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);
410404

411-
uriFreeUriMembersA(uriparser_uris->normalized_uri);
412-
efree(uriparser_uris->normalized_uri);
413-
uriparser_uris->normalized_uri = NULL;
405+
uriFreeUriMembersA(&uriparser_uris->normalized_uri);
414406
}
415407

416408
efree(uriparser_uris);

ext/uri/php_uriparser.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,9 @@
2424
extern const uri_handler_t uriparser_uri_handler;
2525

2626
typedef struct uriparser_uris_t {
27-
UriUriA *uri;
28-
UriUriA *normalized_uri;
27+
UriUriA uri;
28+
UriUriA normalized_uri;
29+
bool normalized_uri_initialized;
2930
} uriparser_uris_t;
3031

3132
PHP_MINIT_FUNCTION(uri_uriparser);

ext/uri/tests/004.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ var_dump(Uri\WhatWg\Url::parse("http://RuPaul's Drag Race All Stars 7 Winners Ca
2929

3030
?>
3131
--EXPECTF--
32-
The specified URI is malformed (MissingSchemeNonRelativeUrl)
32+
The specified URI is malformed
3333
NULL
3434
The specified URI is malformed (MissingSchemeNonRelativeUrl)
3535
NULL

ext/uri/tests/007.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ var_dump($failures);
2525

2626
?>
2727
--EXPECTF--
28-
The specified URI is malformed (PortInvalid)
28+
The specified URI is malformed
2929
The specified URI is malformed (PortInvalid)
3030
array(%d) {
3131
[0]=>

ext/uri/tests/051.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ var_dump($softErrors);
2828

2929
?>
3030
--EXPECTF--
31-
The specified URI is malformed (Ipv4TooManyParts)
31+
The specified URI is malformed
3232
The specified URI is malformed (Ipv4TooManyParts)
3333
string(23) "https://example.com/foo"
3434
array(%d) {

ext/uri/uriparser/src/UriCommon.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,6 @@ unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig);
9696
URI_CHAR URI_FUNC(HexToLetter)(unsigned int value);
9797
URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase);
9898

99-
UriBool URI_FUNC(IsHostSet)(const URI_TYPE(Uri) * uri);
100-
10199
UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest, const URI_TYPE(Uri) * source,
102100
UriMemoryManager * memory);
103101
UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest,

ext/uri/uriparser/src/UriCopy.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
201201
destPrev = destWalker;
202202
sourceWalker = sourceWalker->next;
203203

204-
destUri->pathTail = destPrev;
204+
destUri->pathTail = destWalker;
205205
}
206206
}
207207

0 commit comments

Comments
 (0)