/src/php-src/ext/uri/uriparser/src/UriQuery.c
Line | Count | Source |
1 | | /* |
2 | | * uriparser - RFC 3986 URI parsing library |
3 | | * |
4 | | * Copyright (C) 2007, Weijia Song <songweijia@gmail.com> |
5 | | * Copyright (C) 2007, Sebastian Pipping <sebastian@pipping.org> |
6 | | * All rights reserved. |
7 | | * |
8 | | * Redistribution and use in source and binary forms, with or without |
9 | | * modification, are permitted provided that the following conditions |
10 | | * are met: |
11 | | * |
12 | | * 1. Redistributions of source code must retain the above |
13 | | * copyright notice, this list of conditions and the following |
14 | | * disclaimer. |
15 | | * |
16 | | * 2. Redistributions in binary form must reproduce the above |
17 | | * copyright notice, this list of conditions and the following |
18 | | * disclaimer in the documentation and/or other materials |
19 | | * provided with the distribution. |
20 | | * |
21 | | * 3. Neither the name of the copyright holder nor the names of |
22 | | * its contributors may be used to endorse or promote products |
23 | | * derived from this software without specific prior written |
24 | | * permission. |
25 | | * |
26 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
27 | | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
28 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS |
29 | | * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL |
30 | | * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
31 | | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
32 | | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
33 | | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
34 | | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
35 | | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
36 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED |
37 | | * OF THE POSSIBILITY OF SUCH DAMAGE. |
38 | | */ |
39 | | |
40 | | /* What encodings are enabled? */ |
41 | | #include <uriparser/UriDefsConfig.h> |
42 | | #if (!defined(URI_PASS_ANSI) && !defined(URI_PASS_UNICODE)) |
43 | | /* Include SELF twice */ |
44 | | # ifdef URI_ENABLE_ANSI |
45 | | # define URI_PASS_ANSI 1 |
46 | | # include "UriQuery.c" |
47 | | # undef URI_PASS_ANSI |
48 | | # endif |
49 | | # ifdef URI_ENABLE_UNICODE |
50 | | # define URI_PASS_UNICODE 1 |
51 | | # include "UriQuery.c" |
52 | | # undef URI_PASS_UNICODE |
53 | | # endif |
54 | | #else |
55 | | # ifdef URI_PASS_ANSI |
56 | | # include <uriparser/UriDefsAnsi.h> |
57 | | # else |
58 | | # include <uriparser/UriDefsUnicode.h> |
59 | | # include <wchar.h> |
60 | | # endif |
61 | | |
62 | | # ifndef URI_DOXYGEN |
63 | | # include <uriparser/Uri.h> |
64 | | # include "UriCommon.h" |
65 | | # include "UriMemory.h" |
66 | | # endif |
67 | | |
68 | | # include <limits.h> |
69 | | # include <stddef.h> /* size_t */ |
70 | | # include <stdint.h> // SIZE_MAX |
71 | | |
72 | | static int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, |
73 | | const URI_TYPE(QueryList) * queryList, |
74 | | int maxChars, int * charsWritten, |
75 | | int * charsRequired, UriBool spaceToPlus, |
76 | | UriBool normalizeBreaks); |
77 | | |
78 | | static UriBool URI_FUNC(AppendQueryItem)( |
79 | | URI_TYPE(QueryList) * *prevNext, int * itemCount, const URI_CHAR * keyFirst, |
80 | | const URI_CHAR * keyAfter, const URI_CHAR * valueFirst, const URI_CHAR * valueAfter, |
81 | | UriBool plusToSpace, UriBreakConversion breakConversion, UriMemoryManager * memory); |
82 | | |
83 | | int URI_FUNC(ComposeQueryCharsRequired)(const URI_TYPE(QueryList) * queryList, |
84 | 0 | int * charsRequired) { |
85 | 0 | const UriBool spaceToPlus = URI_TRUE; |
86 | 0 | const UriBool normalizeBreaks = URI_TRUE; |
87 | |
|
88 | 0 | return URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, charsRequired, spaceToPlus, |
89 | 0 | normalizeBreaks); |
90 | 0 | } Unexecuted instantiation: uriComposeQueryCharsRequiredA Unexecuted instantiation: uriComposeQueryCharsRequiredW |
91 | | |
92 | | int URI_FUNC(ComposeQueryCharsRequiredEx)(const URI_TYPE(QueryList) * queryList, |
93 | | int * charsRequired, UriBool spaceToPlus, |
94 | 0 | UriBool normalizeBreaks) { |
95 | 0 | if ((queryList == NULL) || (charsRequired == NULL)) { |
96 | 0 | return URI_ERROR_NULL; |
97 | 0 | } |
98 | | |
99 | 0 | return URI_FUNC(ComposeQueryEngine)(NULL, queryList, 0, NULL, charsRequired, |
100 | 0 | spaceToPlus, normalizeBreaks); |
101 | 0 | } Unexecuted instantiation: uriComposeQueryCharsRequiredExA Unexecuted instantiation: uriComposeQueryCharsRequiredExW |
102 | | |
103 | | int URI_FUNC(ComposeQuery)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, |
104 | 0 | int maxChars, int * charsWritten) { |
105 | 0 | const UriBool spaceToPlus = URI_TRUE; |
106 | 0 | const UriBool normalizeBreaks = URI_TRUE; |
107 | |
|
108 | 0 | return URI_FUNC(ComposeQueryEx)(dest, queryList, maxChars, charsWritten, spaceToPlus, |
109 | 0 | normalizeBreaks); |
110 | 0 | } Unexecuted instantiation: uriComposeQueryA Unexecuted instantiation: uriComposeQueryW |
111 | | |
112 | | int URI_FUNC(ComposeQueryEx)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, |
113 | | int maxChars, int * charsWritten, UriBool spaceToPlus, |
114 | 0 | UriBool normalizeBreaks) { |
115 | 0 | if ((dest == NULL) || (queryList == NULL)) { |
116 | 0 | return URI_ERROR_NULL; |
117 | 0 | } |
118 | | |
119 | 0 | if (maxChars < 1) { |
120 | 0 | return URI_ERROR_OUTPUT_TOO_LARGE; |
121 | 0 | } |
122 | | |
123 | 0 | return URI_FUNC(ComposeQueryEngine)(dest, queryList, maxChars, charsWritten, NULL, |
124 | 0 | spaceToPlus, normalizeBreaks); |
125 | 0 | } Unexecuted instantiation: uriComposeQueryExA Unexecuted instantiation: uriComposeQueryExW |
126 | | |
127 | | int URI_FUNC(ComposeQueryMalloc)(URI_CHAR ** dest, |
128 | 0 | const URI_TYPE(QueryList) * queryList) { |
129 | 0 | const UriBool spaceToPlus = URI_TRUE; |
130 | 0 | const UriBool normalizeBreaks = URI_TRUE; |
131 | |
|
132 | 0 | return URI_FUNC(ComposeQueryMallocEx)(dest, queryList, spaceToPlus, normalizeBreaks); |
133 | 0 | } Unexecuted instantiation: uriComposeQueryMallocA Unexecuted instantiation: uriComposeQueryMallocW |
134 | | |
135 | | int URI_FUNC(ComposeQueryMallocEx)(URI_CHAR ** dest, |
136 | | const URI_TYPE(QueryList) * queryList, |
137 | 0 | UriBool spaceToPlus, UriBool normalizeBreaks) { |
138 | 0 | return URI_FUNC(ComposeQueryMallocExMm)(dest, queryList, spaceToPlus, normalizeBreaks, |
139 | 0 | NULL); |
140 | 0 | } Unexecuted instantiation: uriComposeQueryMallocExA Unexecuted instantiation: uriComposeQueryMallocExW |
141 | | |
142 | | int URI_FUNC(ComposeQueryMallocExMm)(URI_CHAR ** dest, |
143 | | const URI_TYPE(QueryList) * queryList, |
144 | | UriBool spaceToPlus, UriBool normalizeBreaks, |
145 | 0 | UriMemoryManager * memory) { |
146 | 0 | int charsRequired; |
147 | 0 | int res; |
148 | 0 | URI_CHAR * queryString; |
149 | |
|
150 | 0 | if (dest == NULL) { |
151 | 0 | return URI_ERROR_NULL; |
152 | 0 | } |
153 | | |
154 | 0 | URI_CHECK_MEMORY_MANAGER(memory); /* may return */ |
155 | | |
156 | | /* Calculate space */ |
157 | 0 | res = URI_FUNC(ComposeQueryCharsRequiredEx)(queryList, &charsRequired, spaceToPlus, |
158 | 0 | normalizeBreaks); |
159 | 0 | if (res != URI_SUCCESS) { |
160 | 0 | return res; |
161 | 0 | } |
162 | 0 | if (charsRequired == INT_MAX) { |
163 | 0 | return URI_ERROR_MALLOC; |
164 | 0 | } |
165 | 0 | charsRequired++; |
166 | | |
167 | | /* Allocate space */ |
168 | 0 | queryString = memory->calloc(memory, charsRequired, sizeof(URI_CHAR)); |
169 | 0 | if (queryString == NULL) { |
170 | 0 | return URI_ERROR_MALLOC; |
171 | 0 | } |
172 | | |
173 | | /* Put query in */ |
174 | 0 | res = URI_FUNC(ComposeQueryEx)(queryString, queryList, charsRequired, NULL, |
175 | 0 | spaceToPlus, normalizeBreaks); |
176 | 0 | if (res != URI_SUCCESS) { |
177 | 0 | memory->free(memory, queryString); |
178 | 0 | return res; |
179 | 0 | } |
180 | | |
181 | 0 | *dest = queryString; |
182 | 0 | return URI_SUCCESS; |
183 | 0 | } Unexecuted instantiation: uriComposeQueryMallocExMmA Unexecuted instantiation: uriComposeQueryMallocExMmW |
184 | | |
185 | | int URI_FUNC(ComposeQueryEngine)(URI_CHAR * dest, const URI_TYPE(QueryList) * queryList, |
186 | | int maxChars, int * charsWritten, int * charsRequired, |
187 | 0 | UriBool spaceToPlus, UriBool normalizeBreaks) { |
188 | 0 | UriBool firstItem = URI_TRUE; |
189 | 0 | int ampersandLen = 0; /* increased to 1 from second item on */ |
190 | 0 | URI_CHAR * write = dest; |
191 | | |
192 | | /* Subtract terminator */ |
193 | 0 | if (dest == NULL) { |
194 | 0 | *charsRequired = 0; |
195 | 0 | } else { |
196 | 0 | maxChars--; |
197 | 0 | } |
198 | |
|
199 | 0 | while (queryList != NULL) { |
200 | 0 | const URI_CHAR * const key = queryList->key; |
201 | 0 | const URI_CHAR * const value = queryList->value; |
202 | 0 | const int worstCase = (normalizeBreaks == URI_TRUE ? 6 : 3); |
203 | 0 | const size_t keyLen = (key == NULL) ? 0 : URI_STRLEN(key); |
204 | 0 | int keyRequiredChars; |
205 | 0 | const size_t valueLen = (value == NULL) ? 0 : URI_STRLEN(value); |
206 | 0 | int valueRequiredChars; |
207 | |
|
208 | 0 | if ((keyLen >= (size_t)INT_MAX / worstCase) |
209 | 0 | || (valueLen >= (size_t)INT_MAX / worstCase)) { |
210 | 0 | return URI_ERROR_OUTPUT_TOO_LARGE; |
211 | 0 | } |
212 | 0 | keyRequiredChars = worstCase * (int)keyLen; |
213 | 0 | valueRequiredChars = worstCase * (int)valueLen; |
214 | |
|
215 | 0 | if (dest == NULL) { |
216 | 0 | (*charsRequired) += ampersandLen + keyRequiredChars |
217 | 0 | + ((value == NULL) ? 0 : 1 + valueRequiredChars); |
218 | |
|
219 | 0 | if (firstItem == URI_TRUE) { |
220 | 0 | ampersandLen = 1; |
221 | 0 | firstItem = URI_FALSE; |
222 | 0 | } |
223 | 0 | } else { |
224 | 0 | if ((write - dest) + ampersandLen + keyRequiredChars > maxChars) { |
225 | 0 | return URI_ERROR_OUTPUT_TOO_LARGE; |
226 | 0 | } |
227 | | |
228 | | /* Copy key */ |
229 | 0 | if (firstItem == URI_TRUE) { |
230 | 0 | ampersandLen = 1; |
231 | 0 | firstItem = URI_FALSE; |
232 | 0 | } else { |
233 | 0 | write[0] = _UT('&'); |
234 | 0 | write++; |
235 | 0 | } |
236 | 0 | write = URI_FUNC(EscapeEx)(key, key + keyLen, write, spaceToPlus, |
237 | 0 | normalizeBreaks); |
238 | |
|
239 | 0 | if (value != NULL) { |
240 | 0 | if ((write - dest) + 1 + valueRequiredChars > maxChars) { |
241 | 0 | return URI_ERROR_OUTPUT_TOO_LARGE; |
242 | 0 | } |
243 | | |
244 | | /* Copy value */ |
245 | 0 | write[0] = _UT('='); |
246 | 0 | write++; |
247 | 0 | write = URI_FUNC(EscapeEx)(value, value + valueLen, write, spaceToPlus, |
248 | 0 | normalizeBreaks); |
249 | 0 | } |
250 | 0 | } |
251 | | |
252 | 0 | queryList = queryList->next; |
253 | 0 | } |
254 | | |
255 | 0 | if (dest != NULL) { |
256 | 0 | write[0] = _UT('\0'); |
257 | 0 | if (charsWritten != NULL) { |
258 | 0 | const size_t lenInChars = write - dest; |
259 | | |
260 | | // Detect and avoid integer overflow |
261 | 0 | if (lenInChars > INT_MAX - 1) { |
262 | 0 | return URI_ERROR_OUTPUT_TOO_LARGE; |
263 | 0 | } |
264 | | |
265 | 0 | *charsWritten = (int)(lenInChars + 1); /* .. for terminator */ |
266 | 0 | } |
267 | 0 | } |
268 | | |
269 | 0 | return URI_SUCCESS; |
270 | 0 | } Unexecuted instantiation: UriQuery.c:uriComposeQueryEngineA Unexecuted instantiation: UriQuery.c:uriComposeQueryEngineW |
271 | | |
272 | | UriBool URI_FUNC(AppendQueryItem)(URI_TYPE(QueryList) * *prevNext, int * itemCount, |
273 | | const URI_CHAR * keyFirst, const URI_CHAR * keyAfter, |
274 | | const URI_CHAR * valueFirst, |
275 | | const URI_CHAR * valueAfter, UriBool plusToSpace, |
276 | | UriBreakConversion breakConversion, |
277 | 0 | UriMemoryManager * memory) { |
278 | 0 | const size_t keyLen = keyAfter - keyFirst; |
279 | 0 | const size_t valueLen = valueAfter - valueFirst; |
280 | 0 | URI_CHAR * key; |
281 | 0 | URI_CHAR * value; |
282 | |
|
283 | 0 | if ((prevNext == NULL) || (itemCount == NULL) || (keyFirst == NULL) |
284 | 0 | || (keyAfter == NULL) || (keyFirst > keyAfter) || (valueFirst > valueAfter) |
285 | 0 | || ((keyFirst == keyAfter) && (valueFirst == NULL) && (valueAfter == NULL))) { |
286 | 0 | return URI_TRUE; |
287 | 0 | } |
288 | | |
289 | | /* Append new empty item */ |
290 | 0 | *prevNext = memory->malloc(memory, 1 * sizeof(URI_TYPE(QueryList))); |
291 | 0 | if (*prevNext == NULL) { |
292 | 0 | return URI_FALSE; /* Raises malloc error */ |
293 | 0 | } |
294 | 0 | (*prevNext)->next = NULL; |
295 | | |
296 | | // Detect integer overflow |
297 | 0 | if ((keyLen > SIZE_MAX - 1) || (keyLen + 1 > SIZE_MAX / sizeof(URI_CHAR))) { |
298 | 0 | memory->free(memory, *prevNext); |
299 | 0 | *prevNext = NULL; |
300 | 0 | return URI_FALSE; // Raises malloc error |
301 | 0 | } |
302 | | |
303 | | /* Fill key */ |
304 | 0 | key = memory->malloc(memory, (keyLen + 1) * sizeof(URI_CHAR)); |
305 | 0 | if (key == NULL) { |
306 | 0 | memory->free(memory, *prevNext); |
307 | 0 | *prevNext = NULL; |
308 | 0 | return URI_FALSE; /* Raises malloc error */ |
309 | 0 | } |
310 | | |
311 | 0 | key[keyLen] = _UT('\0'); |
312 | 0 | if (keyLen > 0) { |
313 | | /* Copy 1:1 */ |
314 | 0 | memcpy(key, keyFirst, keyLen * sizeof(URI_CHAR)); |
315 | | |
316 | | /* Unescape */ |
317 | 0 | URI_FUNC(UnescapeInPlaceEx)(key, plusToSpace, breakConversion); |
318 | 0 | } |
319 | 0 | (*prevNext)->key = key; |
320 | | |
321 | | /* Fill value */ |
322 | 0 | if (valueFirst != NULL) { |
323 | | // Detect integer overflow |
324 | 0 | if ((valueLen > SIZE_MAX - 1) || (valueLen + 1 > SIZE_MAX / sizeof(URI_CHAR))) { |
325 | 0 | memory->free(memory, key); |
326 | 0 | memory->free(memory, *prevNext); |
327 | 0 | *prevNext = NULL; |
328 | 0 | return URI_FALSE; // Raises malloc error |
329 | 0 | } |
330 | | |
331 | 0 | value = memory->malloc(memory, (valueLen + 1) * sizeof(URI_CHAR)); |
332 | 0 | if (value == NULL) { |
333 | 0 | memory->free(memory, key); |
334 | 0 | memory->free(memory, *prevNext); |
335 | 0 | *prevNext = NULL; |
336 | 0 | return URI_FALSE; /* Raises malloc error */ |
337 | 0 | } |
338 | | |
339 | 0 | value[valueLen] = _UT('\0'); |
340 | 0 | if (valueLen > 0) { |
341 | | /* Copy 1:1 */ |
342 | 0 | memcpy(value, valueFirst, valueLen * sizeof(URI_CHAR)); |
343 | | |
344 | | /* Unescape */ |
345 | 0 | URI_FUNC(UnescapeInPlaceEx)(value, plusToSpace, breakConversion); |
346 | 0 | } |
347 | 0 | (*prevNext)->value = value; |
348 | 0 | } else { |
349 | 0 | value = NULL; |
350 | 0 | } |
351 | 0 | (*prevNext)->value = value; |
352 | |
|
353 | 0 | (*itemCount)++; |
354 | 0 | return URI_TRUE; |
355 | 0 | } Unexecuted instantiation: UriQuery.c:uriAppendQueryItemA Unexecuted instantiation: UriQuery.c:uriAppendQueryItemW |
356 | | |
357 | 0 | void URI_FUNC(FreeQueryList)(URI_TYPE(QueryList) * queryList) { |
358 | 0 | URI_FUNC(FreeQueryListMm)(queryList, NULL); |
359 | 0 | } Unexecuted instantiation: uriFreeQueryListA Unexecuted instantiation: uriFreeQueryListW |
360 | | |
361 | | int URI_FUNC(FreeQueryListMm)(URI_TYPE(QueryList) * queryList, |
362 | 0 | UriMemoryManager * memory) { |
363 | 0 | URI_CHECK_MEMORY_MANAGER(memory); /* may return */ |
364 | 0 | while (queryList != NULL) { |
365 | 0 | URI_TYPE(QueryList) * nextBackup = queryList->next; |
366 | 0 | memory->free(memory, (URI_CHAR *)queryList->key); /* const cast */ |
367 | 0 | memory->free(memory, (URI_CHAR *)queryList->value); /* const cast */ |
368 | 0 | memory->free(memory, queryList); |
369 | 0 | queryList = nextBackup; |
370 | 0 | } |
371 | 0 | return URI_SUCCESS; |
372 | 0 | } Unexecuted instantiation: uriFreeQueryListMmA Unexecuted instantiation: uriFreeQueryListMmW |
373 | | |
374 | | int URI_FUNC(DissectQueryMalloc)(URI_TYPE(QueryList) * *dest, int * itemCount, |
375 | 0 | const URI_CHAR * first, const URI_CHAR * afterLast) { |
376 | 0 | const UriBool plusToSpace = URI_TRUE; |
377 | 0 | const UriBreakConversion breakConversion = URI_BR_DONT_TOUCH; |
378 | |
|
379 | 0 | return URI_FUNC(DissectQueryMallocEx)(dest, itemCount, first, afterLast, plusToSpace, |
380 | 0 | breakConversion); |
381 | 0 | } Unexecuted instantiation: uriDissectQueryMallocA Unexecuted instantiation: uriDissectQueryMallocW |
382 | | |
383 | | int URI_FUNC(DissectQueryMallocEx)(URI_TYPE(QueryList) * *dest, int * itemCount, |
384 | | const URI_CHAR * first, const URI_CHAR * afterLast, |
385 | | UriBool plusToSpace, |
386 | 0 | UriBreakConversion breakConversion) { |
387 | 0 | return URI_FUNC(DissectQueryMallocExMm)(dest, itemCount, first, afterLast, |
388 | 0 | plusToSpace, breakConversion, NULL); |
389 | 0 | } Unexecuted instantiation: uriDissectQueryMallocExA Unexecuted instantiation: uriDissectQueryMallocExW |
390 | | |
391 | | int URI_FUNC(DissectQueryMallocExMm)(URI_TYPE(QueryList) * *dest, int * itemCount, |
392 | | const URI_CHAR * first, const URI_CHAR * afterLast, |
393 | | UriBool plusToSpace, |
394 | | UriBreakConversion breakConversion, |
395 | 0 | UriMemoryManager * memory) { |
396 | 0 | const URI_CHAR * walk = first; |
397 | 0 | const URI_CHAR * keyFirst = first; |
398 | 0 | const URI_CHAR * keyAfter = NULL; |
399 | 0 | const URI_CHAR * valueFirst = NULL; |
400 | 0 | const URI_CHAR * valueAfter = NULL; |
401 | 0 | URI_TYPE(QueryList) ** prevNext = dest; |
402 | 0 | int nullCounter; |
403 | 0 | int * itemsAppended = (itemCount == NULL) ? &nullCounter : itemCount; |
404 | |
|
405 | 0 | if ((dest == NULL) || (first == NULL) || (afterLast == NULL)) { |
406 | 0 | return URI_ERROR_NULL; |
407 | 0 | } |
408 | | |
409 | 0 | if (first > afterLast) { |
410 | 0 | return URI_ERROR_RANGE_INVALID; |
411 | 0 | } |
412 | | |
413 | 0 | URI_CHECK_MEMORY_MANAGER(memory); /* may return */ |
414 | | |
415 | 0 | *dest = NULL; |
416 | 0 | *itemsAppended = 0; |
417 | | |
418 | | /* Parse query string */ |
419 | 0 | for (; walk < afterLast; walk++) { |
420 | 0 | switch (*walk) { |
421 | 0 | case _UT('&'): |
422 | 0 | if (valueFirst != NULL) { |
423 | 0 | valueAfter = walk; |
424 | 0 | } else { |
425 | 0 | keyAfter = walk; |
426 | 0 | } |
427 | |
|
428 | 0 | if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, |
429 | 0 | valueFirst, valueAfter, plusToSpace, |
430 | 0 | breakConversion, memory) |
431 | 0 | == URI_FALSE) { |
432 | | /* Free list we built */ |
433 | 0 | *itemsAppended = 0; |
434 | 0 | URI_FUNC(FreeQueryListMm)(*dest, memory); |
435 | 0 | return URI_ERROR_MALLOC; |
436 | 0 | } |
437 | | |
438 | | /* Make future items children of the current */ |
439 | 0 | if ((prevNext != NULL) && (*prevNext != NULL)) { |
440 | 0 | prevNext = &((*prevNext)->next); |
441 | 0 | } |
442 | |
|
443 | 0 | if (walk + 1 < afterLast) { |
444 | 0 | keyFirst = walk + 1; |
445 | 0 | } else { |
446 | 0 | keyFirst = NULL; |
447 | 0 | } |
448 | 0 | keyAfter = NULL; |
449 | 0 | valueFirst = NULL; |
450 | 0 | valueAfter = NULL; |
451 | 0 | break; |
452 | | |
453 | 0 | case _UT('='): |
454 | | /* NOTE: WE treat the first '=' as a separator, */ |
455 | | /* all following go into the value part */ |
456 | 0 | if (keyAfter == NULL) { |
457 | 0 | keyAfter = walk; |
458 | 0 | if (walk + 1 <= afterLast) { |
459 | 0 | valueFirst = walk + 1; |
460 | 0 | valueAfter = walk + 1; |
461 | 0 | } |
462 | 0 | } |
463 | 0 | break; |
464 | | |
465 | 0 | default: |
466 | 0 | break; |
467 | 0 | } |
468 | 0 | } |
469 | | |
470 | 0 | if (valueFirst != NULL) { |
471 | | /* Must be key/value pair */ |
472 | 0 | valueAfter = walk; |
473 | 0 | } else { |
474 | | /* Must be key only */ |
475 | 0 | keyAfter = walk; |
476 | 0 | } |
477 | |
|
478 | 0 | if (URI_FUNC(AppendQueryItem)(prevNext, itemsAppended, keyFirst, keyAfter, valueFirst, |
479 | 0 | valueAfter, plusToSpace, breakConversion, memory) |
480 | 0 | == URI_FALSE) { |
481 | | /* Free list we built */ |
482 | 0 | *itemsAppended = 0; |
483 | 0 | URI_FUNC(FreeQueryListMm)(*dest, memory); |
484 | 0 | return URI_ERROR_MALLOC; |
485 | 0 | } |
486 | | |
487 | 0 | return URI_SUCCESS; |
488 | 0 | } Unexecuted instantiation: uriDissectQueryMallocExMmA Unexecuted instantiation: uriDissectQueryMallocExMmW |
489 | | |
490 | | #endif |