Skip to content

Commit 441d99b

Browse files
committed
Try to incorporate uriparser_copy_uri into uriparser
1 parent 7144891 commit 441d99b

File tree

5 files changed

+265
-150
lines changed

5 files changed

+265
-150
lines changed

ext/uri/php_uriparser.c

Lines changed: 4 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -28,73 +28,15 @@ static inline size_t get_text_range_length(const UriTextRangeA *range)
2828
return range->afterLast - range->first;
2929
}
3030

31-
static void uriparser_copy_text_range(UriTextRangeA *text_range, UriTextRangeA *new_text_range, bool use_safe)
32-
{
33-
if (text_range->first == NULL || text_range->afterLast == NULL || (text_range->first > text_range->afterLast && !use_safe)) {
34-
new_text_range->first = NULL;
35-
new_text_range->afterLast = NULL;
36-
} else if (text_range->first >= text_range->afterLast && use_safe) {
37-
new_text_range->first = uriSafeToPointToA;
38-
new_text_range->afterLast = uriSafeToPointToA;
39-
} else {
40-
size_t length = get_text_range_length(text_range);
41-
char *dup = emalloc(length);
42-
memcpy(dup, text_range->first, length);
43-
44-
new_text_range->first = dup;
45-
new_text_range->afterLast = dup + length;
46-
}
47-
}
48-
4931
static UriUriA *uriparser_copy_uri(UriUriA *uriparser_uri) // TODO add to uriparser
5032
{
5133
UriUriA *new_uriparser_uri = emalloc(sizeof(UriUriA));
5234

53-
uriparser_copy_text_range(&uriparser_uri->scheme, &new_uriparser_uri->scheme, false);
54-
uriparser_copy_text_range(&uriparser_uri->userInfo, &new_uriparser_uri->userInfo, false);
55-
uriparser_copy_text_range(&uriparser_uri->hostText, &new_uriparser_uri->hostText, true);
56-
if (uriparser_uri->hostData.ip4 == NULL) {
57-
new_uriparser_uri->hostData.ip4 = NULL;
58-
} else {
59-
new_uriparser_uri->hostData.ip4 = emalloc(sizeof(UriIp4));
60-
*(new_uriparser_uri->hostData.ip4) = *(uriparser_uri->hostData.ip4);
61-
}
62-
if (uriparser_uri->hostData.ip6 == NULL) {
63-
new_uriparser_uri->hostData.ip6 = NULL;
64-
} else {
65-
new_uriparser_uri->hostData.ip6 = emalloc(sizeof(UriIp6));
66-
*(new_uriparser_uri->hostData.ip6) = *(uriparser_uri->hostData.ip6);
67-
}
68-
uriparser_copy_text_range(&uriparser_uri->hostData.ipFuture, &new_uriparser_uri->hostData.ipFuture, false);
69-
uriparser_copy_text_range(&uriparser_uri->portText, &new_uriparser_uri->portText, false);
70-
71-
if (uriparser_uri->pathHead != NULL && uriparser_uri->pathTail != NULL) {
72-
new_uriparser_uri->pathHead = emalloc(sizeof(UriPathSegmentA));
73-
uriparser_copy_text_range(&uriparser_uri->pathHead->text, &new_uriparser_uri->pathHead->text, true);
74-
new_uriparser_uri->pathHead->reserved = NULL;
75-
76-
UriPathSegmentA *p = uriparser_uri->pathHead->next;
77-
UriPathSegmentA *new_p = new_uriparser_uri->pathHead;
78-
while (p != NULL && (p->text.first != p->text.afterLast || p->text.first == uriSafeToPointToA)) {
79-
new_p->next = emalloc(sizeof(UriPathSegmentA));
80-
new_p = new_p->next;
81-
uriparser_copy_text_range(&p->text, &new_p->text, true);
82-
new_p->reserved = NULL;
83-
p = p->next;
84-
}
85-
new_p->next = NULL;
86-
new_uriparser_uri->pathTail = new_p;
87-
} else {
88-
new_uriparser_uri->pathHead = NULL;
89-
new_uriparser_uri->pathTail = NULL;
35+
if (uriCopyUriA(new_uriparser_uri, uriparser_uri) != URI_SUCCESS) {
36+
efree(new_uriparser_uri);
37+
return NULL; /* TODO check for null on call sites */
9038
}
9139

92-
uriparser_copy_text_range(&uriparser_uri->query, &new_uriparser_uri->query, false);
93-
uriparser_copy_text_range(&uriparser_uri->fragment, &new_uriparser_uri->fragment, false);
94-
new_uriparser_uri->absolutePath = uriparser_uri->absolutePath;
95-
new_uriparser_uri->owner = true;
96-
new_uriparser_uri->reserved = NULL;
97-
9840
return new_uriparser_uri;
9941
}
10042

@@ -407,7 +349,7 @@ void *uriparser_parse_uri_ex(const zend_string *uri_str, const uriparser_uris_t
407349

408350
UriUriA *absolute_uri = emalloc(sizeof(UriUriA));
409351

410-
if (uriAddBaseUriExA(absolute_uri, uriparser_uri, uriparser_base_urls->uri, URI_RESOLVE_STRICTLY) != URI_SUCCESS) {
352+
if (uriAddBaseUriA(absolute_uri, uriparser_uri, uriparser_base_urls->uri) != URI_SUCCESS) {
411353
uriFreeUriMembersA(uriparser_uri);
412354
efree(uriparser_uri);
413355
efree(absolute_uri);

ext/uri/uriparser/include/uriparser/Uri.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,10 +87,6 @@ extern "C" {
8787

8888

8989

90-
extern const URI_CHAR * const URI_FUNC(SafeToPointTo);
91-
92-
93-
9490
/**
9591
* Specifies a range of characters within a string.
9692
* The range includes all characters from <c>first</c>
@@ -650,6 +646,33 @@ URI_PUBLIC int URI_FUNC(ToString)(URI_CHAR * dest, const URI_TYPE(Uri) * uri,
650646
int maxChars, int * charsWritten);
651647

652648

649+
/**
650+
* Copies a %URI structure.
651+
*
652+
* @param destUri <b>OUT</b>: Output destination
653+
* @param sourceUri <b>IN</b>: %URI to copy
654+
* @param memory <b>IN</b>: Memory manager to use, NULL for default libc
655+
* @return Error code or 0 on success
656+
*
657+
* @since 0.9.8
658+
*/
659+
URI_PUBLIC int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
660+
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory);
661+
662+
663+
664+
/**
665+
* Copies a %URI structure.
666+
*
667+
* @param destUri <b>OUT</b>: Output destination
668+
* @param sourceUri <b>IN</b>: %URI to copy
669+
* @return Error code or 0 on success
670+
*
671+
* @since 0.9.8
672+
*/
673+
URI_PUBLIC int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri, const URI_TYPE(Uri) * sourceUri);
674+
675+
653676

654677
/**
655678
* Determines the components of a %URI that are not normalized.

ext/uri/uriparser/src/UriCommon.c

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
#ifndef URI_DOXYGEN
6565
# include <uriparser/Uri.h>
6666
# include "UriCommon.h"
67+
# include "UriMemory.h"
6768
#endif
6869

6970

@@ -119,6 +120,225 @@ int URI_FUNC(CompareRange)(
119120

120121

121122

123+
UriBool URI_FUNC(CopyRangeEngine)(URI_TYPE(TextRange) * destRange,
124+
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) {
125+
const int lenInChars = (int)(sourceRange->afterLast - sourceRange->first);
126+
const int lenInBytes = lenInChars * sizeof(URI_CHAR);
127+
URI_CHAR * dup = memory->malloc(memory, lenInBytes);
128+
if (dup == NULL) {
129+
return URI_FALSE;
130+
}
131+
memcpy(dup, sourceRange->first, lenInBytes);
132+
destRange->first = dup;
133+
destRange->afterLast = dup + lenInChars;
134+
135+
return URI_TRUE;
136+
}
137+
138+
139+
140+
UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
141+
const URI_TYPE(TextRange) * sourceRange, UriBool useSafe, UriMemoryManager * memory) {
142+
if (sourceRange->first == NULL || sourceRange->afterLast == NULL || (sourceRange->first > sourceRange->afterLast && !useSafe)) {
143+
destRange->first = NULL;
144+
destRange->afterLast = NULL;
145+
} else if (sourceRange->first >= sourceRange->afterLast && useSafe) {
146+
destRange->first = URI_FUNC(SafeToPointTo);
147+
destRange->afterLast = URI_FUNC(SafeToPointTo);
148+
} else {
149+
return URI_FUNC(CopyRangeEngine)(destRange, sourceRange, memory);
150+
}
151+
152+
return URI_TRUE;
153+
}
154+
155+
156+
157+
URI_INLINE void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,
158+
unsigned int revertMask, UriMemoryManager * memory) {
159+
if (revertMask & URI_NORMALIZE_SCHEME) {
160+
/* NOTE: A scheme cannot be the empty string
161+
* so no need to compare .first with .afterLast, here. */
162+
memory->free(memory, (URI_CHAR *)uri->scheme.first);
163+
uri->scheme.first = NULL;
164+
uri->scheme.afterLast = NULL;
165+
}
166+
167+
if (revertMask & URI_NORMALIZE_USER_INFO) {
168+
if (uri->userInfo.first != uri->userInfo.afterLast) {
169+
memory->free(memory, (URI_CHAR *)uri->userInfo.first);
170+
}
171+
uri->userInfo.first = NULL;
172+
uri->userInfo.afterLast = NULL;
173+
}
174+
175+
if (revertMask & URI_NORMALIZE_HOST) {
176+
if (uri->hostData.ipFuture.first != NULL) {
177+
/* IPvFuture */
178+
/* NOTE: An IPvFuture address cannot be the empty string
179+
* so no need to compare .first with .afterLast, here. */
180+
memory->free(memory, (URI_CHAR *)uri->hostData.ipFuture.first);
181+
uri->hostData.ipFuture.first = NULL;
182+
uri->hostData.ipFuture.afterLast = NULL;
183+
uri->hostText.first = NULL;
184+
uri->hostText.afterLast = NULL;
185+
} else if (uri->hostText.first != NULL) {
186+
/* Regname */
187+
if (uri->hostText.first != uri->hostText.afterLast) {
188+
memory->free(memory, (URI_CHAR *)uri->hostText.first);
189+
}
190+
uri->hostText.first = NULL;
191+
uri->hostText.afterLast = NULL;
192+
}
193+
}
194+
195+
/* NOTE: Port cannot happen! */
196+
197+
if (revertMask & URI_NORMALIZE_PATH) {
198+
URI_TYPE(PathSegment) * walker = uri->pathHead;
199+
while (walker != NULL) {
200+
URI_TYPE(PathSegment) * const next = walker->next;
201+
if (walker->text.afterLast > walker->text.first) {
202+
memory->free(memory, (URI_CHAR *)walker->text.first);
203+
}
204+
memory->free(memory, walker);
205+
walker = next;
206+
}
207+
uri->pathHead = NULL;
208+
uri->pathTail = NULL;
209+
}
210+
211+
if (revertMask & URI_NORMALIZE_QUERY) {
212+
if (uri->query.first != uri->query.afterLast) {
213+
memory->free(memory, (URI_CHAR *)uri->query.first);
214+
}
215+
uri->query.first = NULL;
216+
uri->query.afterLast = NULL;
217+
}
218+
219+
if (revertMask & URI_NORMALIZE_FRAGMENT) {
220+
if (uri->fragment.first != uri->fragment.afterLast) {
221+
memory->free(memory, (URI_CHAR *)uri->fragment.first);
222+
}
223+
uri->fragment.first = NULL;
224+
uri->fragment.afterLast = NULL;
225+
}
226+
}
227+
228+
229+
230+
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
231+
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory) {
232+
if (sourceUri == NULL) {
233+
return URI_ERROR_NULL;
234+
}
235+
236+
URI_CHECK_MEMORY_MANAGER(memory); /* may return */
237+
238+
if (URI_FUNC(CopyRange)(&destUri->scheme, &sourceUri->scheme, URI_FALSE, memory) == URI_FALSE) {
239+
return URI_ERROR_MALLOC;
240+
}
241+
242+
if (URI_FUNC(CopyRange)(&destUri->userInfo, &sourceUri->userInfo, URI_FALSE, memory) == URI_FALSE) {
243+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_SCHEME, memory);
244+
return URI_ERROR_MALLOC;
245+
}
246+
247+
if (URI_FUNC(CopyRange)(&destUri->hostText, &sourceUri->hostText, URI_TRUE, memory) == URI_FALSE) {
248+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_USER_INFO, memory);
249+
return URI_ERROR_MALLOC;
250+
}
251+
if (sourceUri->hostData.ip4 == NULL) {
252+
destUri->hostData.ip4 = NULL;
253+
} else {
254+
destUri->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4));
255+
if (destUri->hostData.ip4 == NULL) {
256+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_HOST, memory);
257+
return URI_ERROR_MALLOC;
258+
}
259+
*(destUri->hostData.ip4) = *(sourceUri->hostData.ip4);
260+
}
261+
if (sourceUri->hostData.ip6 == NULL) {
262+
destUri->hostData.ip6 = NULL;
263+
} else {
264+
destUri->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6));
265+
if (destUri->hostData.ip6 == NULL) {
266+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_HOST, memory);
267+
return URI_ERROR_MALLOC;
268+
}
269+
*(destUri->hostData.ip6) = *(sourceUri->hostData.ip6);
270+
}
271+
if (URI_FUNC(CopyRange)(&destUri->hostData.ipFuture, &sourceUri->hostData.ipFuture, URI_FALSE, memory) == URI_FALSE) {
272+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_HOST, memory);
273+
return URI_ERROR_MALLOC;
274+
}
275+
276+
if (URI_FUNC(CopyRange)(&destUri->portText, &sourceUri->portText, URI_FALSE, memory) == URI_FALSE) {
277+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_HOST, memory);
278+
return URI_ERROR_MALLOC;
279+
}
280+
281+
if (sourceUri->pathHead != NULL && sourceUri->pathTail != NULL) {
282+
destUri->pathHead = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
283+
if (destUri->pathHead == NULL) {
284+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_PATH, memory);
285+
return URI_ERROR_MALLOC;
286+
}
287+
if (URI_FUNC(CopyRange)(&destUri->pathHead->text, &sourceUri->pathHead->text, URI_TRUE, memory) == URI_FALSE) {
288+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_PATH, memory);
289+
return URI_ERROR_MALLOC;
290+
}
291+
destUri->pathHead->reserved = NULL;
292+
293+
URI_TYPE(PathSegment) *p = sourceUri->pathHead->next;
294+
URI_TYPE(PathSegment) *newP = destUri->pathHead;
295+
while (p != NULL && (p->text.first != p->text.afterLast || p->text.first == URI_FUNC(SafeToPointTo))) {
296+
newP->next = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
297+
if (newP->next == NULL) {
298+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_PATH, memory);
299+
return URI_ERROR_MALLOC;
300+
}
301+
newP = newP->next;
302+
if (URI_FUNC(CopyRange)(&newP->text, &p->text, URI_TRUE, memory) == URI_FALSE) {
303+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_PATH, memory);
304+
return URI_ERROR_MALLOC;
305+
}
306+
newP->reserved = NULL;
307+
p = p->next;
308+
}
309+
newP->next = NULL;
310+
destUri->pathTail = newP;
311+
} else {
312+
destUri->pathHead = NULL;
313+
destUri->pathTail = NULL;
314+
}
315+
316+
if (URI_FUNC(CopyRange)(&destUri->query, &sourceUri->query, URI_FALSE, memory) == URI_FALSE) {
317+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_PATH, memory);
318+
return URI_ERROR_MALLOC;
319+
}
320+
321+
if (URI_FUNC(CopyRange)(&destUri->fragment, &sourceUri->fragment, URI_FALSE, memory) == URI_FALSE) {
322+
URI_FUNC(PreventLeakage)(destUri, URI_NORMALIZE_QUERY, memory);
323+
return URI_ERROR_MALLOC;
324+
}
325+
326+
destUri->absolutePath = sourceUri->absolutePath;
327+
destUri->owner = URI_TRUE;
328+
destUri->reserved = NULL;
329+
330+
return URI_SUCCESS;
331+
}
332+
333+
334+
335+
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri,
336+
const URI_TYPE(Uri) * sourceUri) {
337+
return URI_FUNC(CopyUriMm)(destUri, sourceUri, NULL);
338+
}
339+
340+
341+
122342
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
123343
UriBool relative, UriBool pathOwned, UriMemoryManager * memory) {
124344
URI_TYPE(PathSegment) * walker;

ext/uri/uriparser/src/UriCommon.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070

7171
/* Used to point to from empty path segments.
7272
* X.first and X.afterLast must be the same non-NULL value then. */
73+
extern const URI_CHAR * const URI_FUNC(SafeToPointTo);
7374
extern const URI_CHAR * const URI_FUNC(ConstPwd);
7475
extern const URI_CHAR * const URI_FUNC(ConstParent);
7576

@@ -81,6 +82,17 @@ int URI_FUNC(CompareRange)(
8182
const URI_TYPE(TextRange) * a,
8283
const URI_TYPE(TextRange) * b);
8384

85+
UriBool URI_FUNC(CopyRangeEngine)(URI_TYPE(TextRange) * destRange,
86+
const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory);
87+
UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
88+
const URI_TYPE(TextRange) * sourceRange, UriBool useSafe, UriMemoryManager * memory);
89+
void URI_FUNC(PreventLeakage)(URI_TYPE(Uri) * uri,
90+
unsigned int revertMask, UriMemoryManager * memory);
91+
int URI_FUNC(CopyUriMm)(URI_TYPE(Uri) * destUri,
92+
const URI_TYPE(Uri) * sourceUri, UriMemoryManager * memory);
93+
int URI_FUNC(CopyUri)(URI_TYPE(Uri) * destUri,
94+
const URI_TYPE(Uri) * sourceUri);
95+
8496
UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,
8597
UriMemoryManager * memory);
8698
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,

0 commit comments

Comments
 (0)