Coverage Report

Created: 2025-07-11 06:39

/src/uriparser/src/UriCommon.c
Line
Count
Source (jump to first uncovered line)
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 "UriCommon.c"
47
#  undef URI_PASS_ANSI
48
# endif
49
# ifdef URI_ENABLE_UNICODE
50
#  define URI_PASS_UNICODE 1
51
#  include "UriCommon.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
63
64
#ifndef URI_DOXYGEN
65
# include <uriparser/Uri.h>
66
# include "UriCommon.h"
67
#endif
68
69
70
71
/*extern*/ const URI_CHAR * const URI_FUNC(SafeToPointTo) = _UT("X");
72
/*extern*/ const URI_CHAR * const URI_FUNC(ConstPwd) = _UT(".");
73
/*extern*/ const URI_CHAR * const URI_FUNC(ConstParent) = _UT("..");
74
75
76
77
7.33k
void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) {
78
7.33k
  if (uri == NULL) {
79
0
    return;
80
0
  }
81
7.33k
  memset(uri, 0, sizeof(URI_TYPE(Uri)));
82
7.33k
}
uriResetUriA
Line
Count
Source
77
7.33k
void URI_FUNC(ResetUri)(URI_TYPE(Uri) * uri) {
78
7.33k
  if (uri == NULL) {
79
0
    return;
80
0
  }
81
7.33k
  memset(uri, 0, sizeof(URI_TYPE(Uri)));
82
7.33k
}
Unexecuted instantiation: uriResetUriW
83
84
85
86
/* Compares two text ranges for equal text content */
87
int URI_FUNC(CompareRange)(
88
    const URI_TYPE(TextRange) * a,
89
0
    const URI_TYPE(TextRange) * b) {
90
0
  int diff;
91
92
  /* NOTE: Both NULL means equal! */
93
0
  if ((a == NULL) || (b == NULL)) {
94
0
    return ((a == NULL) ? 0 : 1) - ((b == NULL) ? 0 : 1);
95
0
  }
96
97
  /* NOTE: Both NULL means equal! */
98
0
  if ((a->first == NULL) || (b->first == NULL)) {
99
0
    return ((a->first == NULL) ? 0 : 1) - ((b->first == NULL) ? 0 : 1);
100
0
  }
101
102
0
  diff = ((int)(a->afterLast - a->first) - (int)(b->afterLast - b->first));
103
0
  if (diff > 0) {
104
0
    return 1;
105
0
  } else if (diff < 0) {
106
0
    return -1;
107
0
  }
108
109
0
  diff = URI_STRNCMP(a->first, b->first, (a->afterLast - a->first));
110
111
0
  if (diff > 0) {
112
0
    return 1;
113
0
  } else if (diff < 0) {
114
0
    return -1;
115
0
  }
116
117
0
  return diff;
118
0
}
Unexecuted instantiation: uriCompareRangeA
Unexecuted instantiation: uriCompareRangeW
119
120
121
122
UriBool URI_FUNC(CopyRange)(URI_TYPE(TextRange) * destRange,
123
0
    const URI_TYPE(TextRange) * sourceRange, UriMemoryManager * memory) {
124
0
  const int lenInChars = (int)(sourceRange->afterLast - sourceRange->first);
125
0
  const int lenInBytes = lenInChars * sizeof(URI_CHAR);
126
0
  URI_CHAR * dup = memory->malloc(memory, lenInBytes);
127
0
  if (dup == NULL) {
128
0
    return URI_FALSE;
129
0
  }
130
0
  memcpy(dup, sourceRange->first, lenInBytes);
131
0
  destRange->first = dup;
132
0
  destRange->afterLast = dup + lenInChars;
133
134
0
  return URI_TRUE;
135
0
}
Unexecuted instantiation: uriCopyRangeA
Unexecuted instantiation: uriCopyRangeW
136
137
138
139
UriBool URI_FUNC(CopyRangeAsNeeded)(URI_TYPE(TextRange) * destRange,
140
0
    const URI_TYPE(TextRange) * sourceRange, UriBool useSafe, UriMemoryManager * memory) {
141
0
  if (sourceRange->first == NULL) {
142
0
    destRange->first = NULL;
143
0
    destRange->afterLast = NULL;
144
0
  } else if (sourceRange->first == sourceRange->afterLast && useSafe) {
145
0
    destRange->first = URI_FUNC(SafeToPointTo);
146
0
    destRange->afterLast = URI_FUNC(SafeToPointTo);
147
0
  } else {
148
0
    return URI_FUNC(CopyRange)(destRange, sourceRange, memory);
149
0
  }
150
151
0
  return URI_TRUE;
152
0
}
Unexecuted instantiation: uriCopyRangeAsNeededA
Unexecuted instantiation: uriCopyRangeAsNeededW
153
154
155
156
UriBool URI_FUNC(RemoveDotSegmentsEx)(URI_TYPE(Uri) * uri,
157
0
    UriBool relative, UriBool pathOwned, UriMemoryManager * memory) {
158
0
  URI_TYPE(PathSegment) * walker;
159
0
  if ((uri == NULL) || (uri->pathHead == NULL)) {
160
0
    return URI_TRUE;
161
0
  }
162
163
0
  walker = uri->pathHead;
164
0
  walker->reserved = NULL; /* Prev pointer */
165
0
  do {
166
0
    UriBool removeSegment = URI_FALSE;
167
0
    int len = (int)(walker->text.afterLast - walker->text.first);
168
0
    switch (len) {
169
0
    case 1:
170
0
      if ((walker->text.first)[0] == _UT('.')) {
171
        /* "." segment -> remove if not essential */
172
0
        URI_TYPE(PathSegment) * const prev = walker->reserved;
173
0
        URI_TYPE(PathSegment) * const nextBackup = walker->next;
174
175
        /*
176
         * Is this dot segment essential,
177
         * i.e. is there a chance of changing semantics by dropping this dot segment?
178
         *
179
         * For example, changing "./http://foo" into "http://foo" would change semantics
180
         * and hence the dot segment is essential to that case and cannot be removed.
181
         */
182
0
        removeSegment = URI_TRUE;
183
0
        if (relative && (walker == uri->pathHead) && (walker->next != NULL)) {
184
0
          const URI_CHAR * ch = walker->next->text.first;
185
0
          for (; ch < walker->next->text.afterLast; ch++) {
186
0
            if (*ch == _UT(':')) {
187
0
              removeSegment = URI_FALSE;
188
0
              break;
189
0
            }
190
0
          }
191
0
        }
192
193
0
        if (removeSegment) {
194
          /* .. then let's go remove that segment. */
195
          /* Last segment? */
196
0
          if (walker->next != NULL) {
197
            /* Not last segment, i.e. first or middle segment
198
             * OLD: (prev|NULL) <- walker <- next
199
             * NEW: (prev|NULL) <----------- next */
200
0
            walker->next->reserved = prev;
201
202
0
            if (prev == NULL) {
203
              /* First but not last segment
204
               * OLD: head -> walker -> next
205
               * NEW: head -----------> next */
206
0
              uri->pathHead = walker->next;
207
0
            } else {
208
              /* Middle segment
209
               * OLD: prev -> walker -> next
210
               * NEW: prev -----------> next */
211
0
              prev->next = walker->next;
212
0
            }
213
214
0
            if (pathOwned && (walker->text.first != walker->text.afterLast)) {
215
0
              memory->free(memory, (URI_CHAR *)walker->text.first);
216
0
            }
217
0
            memory->free(memory, walker);
218
0
          } else {
219
            /* Last segment */
220
0
            if (pathOwned && (walker->text.first != walker->text.afterLast)) {
221
0
              memory->free(memory, (URI_CHAR *)walker->text.first);
222
0
            }
223
224
0
            if (prev == NULL) {
225
              /* Last and first */
226
0
              if (URI_FUNC(HasHost)(uri)) {
227
                /* Replace "." with empty segment to represent trailing slash */
228
0
                walker->text.first = URI_FUNC(SafeToPointTo);
229
0
                walker->text.afterLast = URI_FUNC(SafeToPointTo);
230
0
              } else {
231
0
                memory->free(memory, walker);
232
233
0
                uri->pathHead = NULL;
234
0
                uri->pathTail = NULL;
235
0
              }
236
0
            } else {
237
              /* Last but not first, replace "." with empty segment to represent trailing slash */
238
0
              walker->text.first = URI_FUNC(SafeToPointTo);
239
0
              walker->text.afterLast = URI_FUNC(SafeToPointTo);
240
0
            }
241
0
          }
242
243
0
          walker = nextBackup;
244
0
        }
245
0
      }
246
0
      break;
247
248
0
    case 2:
249
0
      if (((walker->text.first)[0] == _UT('.'))
250
0
          && ((walker->text.first)[1] == _UT('.'))) {
251
        /* Path ".." -> remove this and the previous segment */
252
0
        URI_TYPE(PathSegment) * const prev = walker->reserved;
253
0
        URI_TYPE(PathSegment) * prevPrev;
254
0
        URI_TYPE(PathSegment) * const nextBackup = walker->next;
255
256
0
        removeSegment = URI_TRUE;
257
0
        if (relative) {
258
0
          if (prev == NULL) {
259
            /* We cannot remove traversal beyond because the
260
             * URI is relative and may be resolved later.
261
             * So we can simplify "a/../b/d" to "b/d" but
262
             * we cannot simplify "../b/d" (outside of reference resolution). */
263
0
            removeSegment = URI_FALSE;
264
0
          } else if ((prev != NULL)
265
0
              && ((prev->text.afterLast - prev->text.first) == 2)
266
0
              && ((prev->text.first)[0] == _UT('.'))
267
0
              && ((prev->text.first)[1] == _UT('.'))) {
268
            /* We need to protect against mis-simplifying "a/../../b" to "a/b". */
269
0
            removeSegment = URI_FALSE;
270
0
          }
271
0
        }
272
273
0
        if (removeSegment) {
274
0
          if (prev != NULL) {
275
            /* Not first segment */
276
0
            prevPrev = prev->reserved;
277
0
            if (prevPrev != NULL) {
278
              /* Not even prev is the first one
279
               * OLD: prevPrev -> prev -> walker -> (next|NULL)
280
               * NEW: prevPrev -------------------> (next|NULL) */
281
0
              prevPrev->next = walker->next;
282
0
              if (walker->next != NULL) {
283
                /* Update parent relationship as well
284
                 * OLD: prevPrev <- prev <- walker <- next
285
                 * NEW: prevPrev <------------------- next */
286
0
                walker->next->reserved = prevPrev;
287
0
              } else {
288
                /* Last segment -> insert "" segment to represent trailing slash, update tail */
289
0
                URI_TYPE(PathSegment) * const segment = memory->calloc(memory, 1, sizeof(URI_TYPE(PathSegment)));
290
0
                if (segment == NULL) {
291
0
                  if (pathOwned && (walker->text.first != walker->text.afterLast)) {
292
0
                    memory->free(memory, (URI_CHAR *)walker->text.first);
293
0
                  }
294
0
                  memory->free(memory, walker);
295
296
0
                  if (pathOwned && (prev->text.first != prev->text.afterLast)) {
297
0
                    memory->free(memory, (URI_CHAR *)prev->text.first);
298
0
                  }
299
0
                  memory->free(memory, prev);
300
301
0
                  return URI_FALSE; /* Raises malloc error */
302
0
                }
303
0
                segment->text.first = URI_FUNC(SafeToPointTo);
304
0
                segment->text.afterLast = URI_FUNC(SafeToPointTo);
305
0
                prevPrev->next = segment;
306
0
                uri->pathTail = segment;
307
0
              }
308
309
0
              if (pathOwned && (walker->text.first != walker->text.afterLast)) {
310
0
                memory->free(memory, (URI_CHAR *)walker->text.first);
311
0
              }
312
0
              memory->free(memory, walker);
313
314
0
              if (pathOwned && (prev->text.first != prev->text.afterLast)) {
315
0
                memory->free(memory, (URI_CHAR *)prev->text.first);
316
0
              }
317
0
              memory->free(memory, prev);
318
319
0
              walker = nextBackup;
320
0
            } else {
321
              /* Prev is the first segment */
322
0
              if (walker->next != NULL) {
323
0
                uri->pathHead = walker->next;
324
0
                walker->next->reserved = NULL;
325
326
0
                if (pathOwned && (walker->text.first != walker->text.afterLast)) {
327
0
                  memory->free(memory, (URI_CHAR *)walker->text.first);
328
0
                }
329
0
                memory->free(memory, walker);
330
0
              } else {
331
                /* Re-use segment for "" path segment to represent trailing slash, update tail */
332
0
                URI_TYPE(PathSegment) * const segment = walker;
333
0
                if (pathOwned && (segment->text.first != segment->text.afterLast)) {
334
0
                  memory->free(memory, (URI_CHAR *)segment->text.first);
335
0
                }
336
0
                segment->text.first = URI_FUNC(SafeToPointTo);
337
0
                segment->text.afterLast = URI_FUNC(SafeToPointTo);
338
0
                uri->pathHead = segment;
339
0
                uri->pathTail = segment;
340
0
              }
341
342
0
              if (pathOwned && (prev->text.first != prev->text.afterLast)) {
343
0
                memory->free(memory, (URI_CHAR *)prev->text.first);
344
0
              }
345
0
              memory->free(memory, prev);
346
347
0
              walker = nextBackup;
348
0
            }
349
0
          } else {
350
0
            URI_TYPE(PathSegment) * const anotherNextBackup = walker->next;
351
0
            int freeWalker = URI_TRUE;
352
353
            /* First segment */
354
0
            if (walker->next != NULL) {
355
              /* First segment of multiple -> update head
356
               * OLD: head -> walker -> next
357
               * NEW: head -----------> next */
358
0
              uri->pathHead = walker->next;
359
360
              /* Update parent link as well
361
               * OLD: head <- walker <- next
362
               * NEW: head <----------- next */
363
0
              walker->next->reserved = NULL;
364
0
            } else {
365
0
              if (uri->absolutePath) {
366
                /* First and only segment -> update head
367
                 * OLD: head -> walker -> NULL
368
                 * NEW: head -----------> NULL */
369
0
                uri->pathHead = NULL;
370
371
                /* Last segment -> update tail
372
                 * OLD: tail -> walker
373
                 * NEW: tail -> NULL */
374
0
                uri->pathTail = NULL;
375
0
              } else {
376
                /* Re-use segment for "" path segment to represent trailing slash,
377
                 * then update head and tail */
378
0
                if (pathOwned && (walker->text.first != walker->text.afterLast)) {
379
0
                  memory->free(memory, (URI_CHAR *)walker->text.first);
380
0
                }
381
0
                walker->text.first = URI_FUNC(SafeToPointTo);
382
0
                walker->text.afterLast = URI_FUNC(SafeToPointTo);
383
0
                freeWalker = URI_FALSE;
384
0
              }
385
0
            }
386
387
0
            if (freeWalker) {
388
0
              if (pathOwned && (walker->text.first != walker->text.afterLast)) {
389
0
                memory->free(memory, (URI_CHAR *)walker->text.first);
390
0
              }
391
0
              memory->free(memory, walker);
392
0
            }
393
394
0
            walker = anotherNextBackup;
395
0
          }
396
0
        }
397
0
      }
398
0
      break;
399
0
    } /* end of switch */
400
401
0
    if (!removeSegment) {
402
      /* .. then let's move to the next element, and start again. */
403
0
      if (walker->next != NULL) {
404
0
        walker->next->reserved = walker;
405
0
      } else {
406
        /* Last segment -> update tail */
407
0
        uri->pathTail = walker;
408
0
      }
409
0
      walker = walker->next;
410
0
    }
411
0
  } while (walker != NULL);
412
413
0
  return URI_TRUE;
414
0
}
Unexecuted instantiation: uriRemoveDotSegmentsExA
Unexecuted instantiation: uriRemoveDotSegmentsExW
415
416
417
418
/* Properly removes "." and ".." path segments */
419
UriBool URI_FUNC(RemoveDotSegmentsAbsolute)(URI_TYPE(Uri) * uri,
420
0
    UriMemoryManager * memory) {
421
0
  const UriBool ABSOLUTE = URI_FALSE;
422
0
  if (uri == NULL) {
423
0
    return URI_TRUE;
424
0
  }
425
0
  return URI_FUNC(RemoveDotSegmentsEx)(uri, ABSOLUTE, uri->owner, memory);
426
0
}
Unexecuted instantiation: uriRemoveDotSegmentsAbsoluteA
Unexecuted instantiation: uriRemoveDotSegmentsAbsoluteW
427
428
429
430
0
unsigned char URI_FUNC(HexdigToInt)(URI_CHAR hexdig) {
431
0
  switch (hexdig) {
432
0
  case _UT('0'):
433
0
  case _UT('1'):
434
0
  case _UT('2'):
435
0
  case _UT('3'):
436
0
  case _UT('4'):
437
0
  case _UT('5'):
438
0
  case _UT('6'):
439
0
  case _UT('7'):
440
0
  case _UT('8'):
441
0
  case _UT('9'):
442
0
    return (unsigned char)(9 + hexdig - _UT('9'));
443
444
0
  case _UT('a'):
445
0
  case _UT('b'):
446
0
  case _UT('c'):
447
0
  case _UT('d'):
448
0
  case _UT('e'):
449
0
  case _UT('f'):
450
0
    return (unsigned char)(15 + hexdig - _UT('f'));
451
452
0
  case _UT('A'):
453
0
  case _UT('B'):
454
0
  case _UT('C'):
455
0
  case _UT('D'):
456
0
  case _UT('E'):
457
0
  case _UT('F'):
458
0
    return (unsigned char)(15 + hexdig - _UT('F'));
459
460
0
  default:
461
0
    return 0;
462
0
  }
463
0
}
Unexecuted instantiation: uriHexdigToIntA
Unexecuted instantiation: uriHexdigToIntW
464
465
466
467
0
URI_CHAR URI_FUNC(HexToLetterEx)(unsigned int value, UriBool uppercase) {
468
0
  switch (value) {
469
0
  case  0: return _UT('0');
470
0
  case  1: return _UT('1');
471
0
  case  2: return _UT('2');
472
0
  case  3: return _UT('3');
473
0
  case  4: return _UT('4');
474
0
  case  5: return _UT('5');
475
0
  case  6: return _UT('6');
476
0
  case  7: return _UT('7');
477
0
  case  8: return _UT('8');
478
0
  case  9: return _UT('9');
479
480
0
  case 10: return (uppercase == URI_TRUE) ? _UT('A') : _UT('a');
481
0
  case 11: return (uppercase == URI_TRUE) ? _UT('B') : _UT('b');
482
0
  case 12: return (uppercase == URI_TRUE) ? _UT('C') : _UT('c');
483
0
  case 13: return (uppercase == URI_TRUE) ? _UT('D') : _UT('d');
484
0
  case 14: return (uppercase == URI_TRUE) ? _UT('E') : _UT('e');
485
0
  default: return (uppercase == URI_TRUE) ? _UT('F') : _UT('f');
486
0
  }
487
0
}
Unexecuted instantiation: uriHexToLetterExA
Unexecuted instantiation: uriHexToLetterExW
488
489
490
491
/* Checks if a URI has the host component set. */
492
2.02k
UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri) {
493
  /* NOTE: .hostData.ipFuture.first is not being checked,   *
494
   *       because we do check .hostText.first and          *
495
   *       .hostData.ipFuture.first has to be identical to  *
496
   *       .hostText.first if set, and hence there is       *
497
   *       no more information to be gained.                */
498
2.02k
  return (uri != NULL)
499
2.02k
      && ((uri->hostText.first != NULL)
500
2.02k
        || (uri->hostData.ip4 != NULL)
501
2.02k
        || (uri->hostData.ip6 != NULL)
502
2.02k
      );
503
2.02k
}
uriHasHostA
Line
Count
Source
492
2.02k
UriBool URI_FUNC(HasHost)(const URI_TYPE(Uri) * uri) {
493
  /* NOTE: .hostData.ipFuture.first is not being checked,   *
494
   *       because we do check .hostText.first and          *
495
   *       .hostData.ipFuture.first has to be identical to  *
496
   *       .hostText.first if set, and hence there is       *
497
   *       no more information to be gained.                */
498
2.02k
  return (uri != NULL)
499
2.02k
      && ((uri->hostText.first != NULL)
500
2.02k
        || (uri->hostData.ip4 != NULL)
501
2.02k
        || (uri->hostData.ip6 != NULL)
502
2.02k
      );
503
2.02k
}
Unexecuted instantiation: uriHasHostW
504
505
506
507
/* Copies the path segment list from one URI to another. */
508
UriBool URI_FUNC(CopyPath)(URI_TYPE(Uri) * dest,
509
0
    const URI_TYPE(Uri) * source, UriMemoryManager * memory) {
510
0
  if (source->pathHead == NULL) {
511
    /* No path component */
512
0
    dest->pathHead = NULL;
513
0
    dest->pathTail = NULL;
514
0
  } else {
515
    /* Copy list but not the text contained */
516
0
    URI_TYPE(PathSegment) * sourceWalker = source->pathHead;
517
0
    URI_TYPE(PathSegment) * destPrev = NULL;
518
0
    do {
519
0
      URI_TYPE(PathSegment) * cur = memory->malloc(memory, sizeof(URI_TYPE(PathSegment)));
520
0
      if (cur == NULL) {
521
        /* Fix broken list */
522
0
        if (destPrev != NULL) {
523
0
          destPrev->next = NULL;
524
0
        }
525
0
        return URI_FALSE; /* Raises malloc error */
526
0
      }
527
528
      /* From this functions usage we know that *
529
       * the dest URI cannot be uri->owner      */
530
0
      cur->text = sourceWalker->text;
531
0
      if (destPrev == NULL) {
532
        /* First segment ever */
533
0
        dest->pathHead = cur;
534
0
      } else {
535
0
        destPrev->next = cur;
536
0
      }
537
0
      destPrev = cur;
538
0
      sourceWalker = sourceWalker->next;
539
0
    } while (sourceWalker != NULL);
540
0
    dest->pathTail = destPrev;
541
0
    dest->pathTail->next = NULL;
542
0
  }
543
544
0
  dest->absolutePath = source->absolutePath;
545
0
  return URI_TRUE;
546
0
}
Unexecuted instantiation: uriCopyPathA
Unexecuted instantiation: uriCopyPathW
547
548
549
550
/* Copies the authority part of an URI over to another. */
551
UriBool URI_FUNC(CopyAuthority)(URI_TYPE(Uri) * dest,
552
0
    const URI_TYPE(Uri) * source, UriMemoryManager * memory) {
553
  /* From this functions usage we know that *
554
   * the dest URI cannot be uri->owner      */
555
  
556
  /* Copy userInfo */
557
0
  dest->userInfo = source->userInfo;
558
559
  /* Copy hostText */
560
0
  dest->hostText = source->hostText;
561
562
  /* Copy hostData */
563
0
  if (source->hostData.ip4 != NULL) {
564
0
    dest->hostData.ip4 = memory->malloc(memory, sizeof(UriIp4));
565
0
    if (dest->hostData.ip4 == NULL) {
566
0
      return URI_FALSE; /* Raises malloc error */
567
0
    }
568
0
    *(dest->hostData.ip4) = *(source->hostData.ip4);
569
0
    dest->hostData.ip6 = NULL;
570
0
    dest->hostData.ipFuture.first = NULL;
571
0
    dest->hostData.ipFuture.afterLast = NULL;
572
0
  } else if (source->hostData.ip6 != NULL) {
573
0
    dest->hostData.ip4 = NULL;
574
0
    dest->hostData.ip6 = memory->malloc(memory, sizeof(UriIp6));
575
0
    if (dest->hostData.ip6 == NULL) {
576
0
      return URI_FALSE; /* Raises malloc error */
577
0
    }
578
0
    *(dest->hostData.ip6) = *(source->hostData.ip6);
579
0
    dest->hostData.ipFuture.first = NULL;
580
0
    dest->hostData.ipFuture.afterLast = NULL;
581
0
  } else {
582
0
    dest->hostData.ip4 = NULL;
583
0
    dest->hostData.ip6 = NULL;
584
0
    dest->hostData.ipFuture = source->hostData.ipFuture;
585
0
  }
586
587
  /* Copy portText */
588
0
  dest->portText = source->portText;
589
590
0
  return URI_TRUE;
591
0
}
Unexecuted instantiation: uriCopyAuthorityA
Unexecuted instantiation: uriCopyAuthorityW
592
593
594
595
UriBool URI_FUNC(FixAmbiguity)(URI_TYPE(Uri) * uri,
596
0
    UriMemoryManager * memory) {
597
0
  URI_TYPE(PathSegment) * segment;
598
599
0
  if (  /* Case 1: absolute path, empty first segment */
600
0
      (uri->absolutePath
601
0
      && (uri->pathHead != NULL)
602
0
      && (uri->pathHead->text.afterLast == uri->pathHead->text.first))
603
604
      /* Case 2: relative path, empty first and second segment */
605
0
      || (!uri->absolutePath
606
0
      && (uri->pathHead != NULL)
607
0
      && (uri->pathHead->next != NULL)
608
0
      && (uri->pathHead->text.afterLast == uri->pathHead->text.first)
609
0
      && (uri->pathHead->next->text.afterLast == uri->pathHead->next->text.first))) {
610
    /* NOOP */
611
0
  } else {
612
0
    return URI_TRUE;
613
0
  }
614
615
0
  segment = memory->malloc(memory, 1 * sizeof(URI_TYPE(PathSegment)));
616
0
  if (segment == NULL) {
617
0
    return URI_FALSE; /* Raises malloc error */
618
0
  }
619
620
  /* Insert "." segment in front */
621
0
  segment->next = uri->pathHead;
622
0
  segment->text.first = URI_FUNC(ConstPwd);
623
0
  segment->text.afterLast = URI_FUNC(ConstPwd) + 1;
624
0
  uri->pathHead = segment;
625
0
  return URI_TRUE;
626
0
}
Unexecuted instantiation: uriFixAmbiguityA
Unexecuted instantiation: uriFixAmbiguityW
627
628
629
630
void URI_FUNC(FixEmptyTrailSegment)(URI_TYPE(Uri) * uri,
631
2.02k
    UriMemoryManager * memory) {
632
  /* Fix path if only one empty segment */
633
2.02k
  if (!uri->absolutePath
634
2.02k
      && !URI_FUNC(HasHost)(uri)
635
2.02k
      && (uri->pathHead != NULL)
636
2.02k
      && (uri->pathHead->next == NULL)
637
2.02k
      && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) {
638
0
    memory->free(memory, uri->pathHead);
639
0
    uri->pathHead = NULL;
640
0
    uri->pathTail = NULL;
641
0
  }
642
2.02k
}
uriFixEmptyTrailSegmentA
Line
Count
Source
631
2.02k
    UriMemoryManager * memory) {
632
  /* Fix path if only one empty segment */
633
2.02k
  if (!uri->absolutePath
634
2.02k
      && !URI_FUNC(HasHost)(uri)
635
2.02k
      && (uri->pathHead != NULL)
636
2.02k
      && (uri->pathHead->next == NULL)
637
2.02k
      && (uri->pathHead->text.first == uri->pathHead->text.afterLast)) {
638
0
    memory->free(memory, uri->pathHead);
639
0
    uri->pathHead = NULL;
640
0
    uri->pathTail = NULL;
641
0
  }
642
2.02k
}
Unexecuted instantiation: uriFixEmptyTrailSegmentW
643
644
645
646
#endif