Coverage Report

Created: 2025-11-16 06:23

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/php-src/ext/uri/uriparser/src/UriRecompose.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 "UriRecompose.c"
47
#    undef URI_PASS_ANSI
48
#  endif
49
#  ifdef URI_ENABLE_UNICODE
50
#    define URI_PASS_UNICODE 1
51
#    include "UriRecompose.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
#  endif
66
67
static int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(Uri) * uri,
68
                                    int maxChars, int * charsWritten,
69
                                    int * charsRequired);
70
71
0
int URI_FUNC(ToStringCharsRequired)(const URI_TYPE(Uri) * uri, int * charsRequired) {
72
0
    const int MAX_CHARS = ((unsigned int)-1) >> 1;
73
0
    return URI_FUNC(ToStringEngine)(NULL, uri, MAX_CHARS, NULL, charsRequired);
74
0
}
Unexecuted instantiation: uriToStringCharsRequiredA
Unexecuted instantiation: uriToStringCharsRequiredW
75
76
int URI_FUNC(ToString)(URI_CHAR * dest, const URI_TYPE(Uri) * uri, int maxChars,
77
0
                       int * charsWritten) {
78
0
    return URI_FUNC(ToStringEngine)(dest, uri, maxChars, charsWritten, NULL);
79
0
}
Unexecuted instantiation: uriToStringA
Unexecuted instantiation: uriToStringW
80
81
static URI_INLINE int URI_FUNC(ToStringEngine)(URI_CHAR * dest, const URI_TYPE(Uri) * uri,
82
                                               int maxChars, int * charsWritten,
83
0
                                               int * charsRequired) {
84
0
    int written = 0;
85
0
    if ((uri == NULL) || ((dest == NULL) && (charsRequired == NULL))) {
86
0
        if (charsWritten != NULL) {
87
0
            *charsWritten = 0;
88
0
        }
89
0
        return URI_ERROR_NULL;
90
0
    }
91
92
0
    if (maxChars < 1) {
93
0
        if (charsWritten != NULL) {
94
0
            *charsWritten = 0;
95
0
        }
96
0
        return URI_ERROR_TOSTRING_TOO_LONG;
97
0
    }
98
0
    maxChars--; /* So we don't have to subtract 1 for '\0' all the time */
99
100
    /* NOTE: The curly brackets here force deeper indent (and that's all) */
101
0
    {
102
0
        {
103
0
            {
104
                /* clang-format off */
105
    /* [01/19] result = "" */
106
                /* clang-format on */
107
0
                if (dest != NULL) {
108
0
                    dest[0] = _UT('\0');
109
0
                } else {
110
0
                    (*charsRequired) = 0;
111
0
                }
112
                /* clang-format off */
113
    /* [02/19] if defined(scheme) then */
114
                /* clang-format on */
115
0
                if (uri->scheme.first != NULL) {
116
                    /* clang-format off */
117
    /* [03/19]     append scheme to result; */
118
                    /* clang-format on */
119
0
                    const int charsToWrite =
120
0
                        (int)(uri->scheme.afterLast - uri->scheme.first);
121
0
                    if (dest != NULL) {
122
0
                        if (written + charsToWrite <= maxChars) {
123
0
                            memcpy(dest + written, uri->scheme.first,
124
0
                                   charsToWrite * sizeof(URI_CHAR));
125
0
                            written += charsToWrite;
126
0
                        } else {
127
0
                            dest[0] = _UT('\0');
128
0
                            if (charsWritten != NULL) {
129
0
                                *charsWritten = 0;
130
0
                            }
131
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
132
0
                        }
133
0
                    } else {
134
0
                        (*charsRequired) += charsToWrite;
135
0
                    }
136
                    /* clang-format off */
137
    /* [04/19]     append ":" to result; */
138
                    /* clang-format on */
139
0
                    if (dest != NULL) {
140
0
                        if (written + 1 <= maxChars) {
141
0
                            memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR));
142
0
                            written += 1;
143
0
                        } else {
144
0
                            dest[0] = _UT('\0');
145
0
                            if (charsWritten != NULL) {
146
0
                                *charsWritten = 0;
147
0
                            }
148
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
149
0
                        }
150
0
                    } else {
151
0
                        (*charsRequired) += 1;
152
0
                    }
153
                    /* clang-format off */
154
    /* [05/19] endif; */
155
                    /* clang-format on */
156
0
                }
157
                /* clang-format off */
158
    /* [06/19] if defined(authority) then */
159
                /* clang-format on */
160
0
                if (URI_FUNC(HasHost)(uri)) {
161
                    /* clang-format off */
162
    /* [07/19]     append "//" to result; */
163
                    /* clang-format on */
164
0
                    if (dest != NULL) {
165
0
                        if (written + 2 <= maxChars) {
166
0
                            memcpy(dest + written, _UT("//"), 2 * sizeof(URI_CHAR));
167
0
                            written += 2;
168
0
                        } else {
169
0
                            dest[0] = _UT('\0');
170
0
                            if (charsWritten != NULL) {
171
0
                                *charsWritten = 0;
172
0
                            }
173
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
174
0
                        }
175
0
                    } else {
176
0
                        (*charsRequired) += 2;
177
0
                    }
178
                    /* clang-format off */
179
    /* [08/19]     append authority to result; */
180
                    /* clang-format on */
181
                    /* UserInfo */
182
0
                    if (uri->userInfo.first != NULL) {
183
0
                        const int charsToWrite =
184
0
                            (int)(uri->userInfo.afterLast - uri->userInfo.first);
185
0
                        if (dest != NULL) {
186
0
                            if (written + charsToWrite <= maxChars) {
187
0
                                memcpy(dest + written, uri->userInfo.first,
188
0
                                       charsToWrite * sizeof(URI_CHAR));
189
0
                                written += charsToWrite;
190
0
                            } else {
191
0
                                dest[0] = _UT('\0');
192
0
                                if (charsWritten != NULL) {
193
0
                                    *charsWritten = 0;
194
0
                                }
195
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
196
0
                            }
197
198
0
                            if (written + 1 <= maxChars) {
199
0
                                memcpy(dest + written, _UT("@"), 1 * sizeof(URI_CHAR));
200
0
                                written += 1;
201
0
                            } else {
202
0
                                dest[0] = _UT('\0');
203
0
                                if (charsWritten != NULL) {
204
0
                                    *charsWritten = 0;
205
0
                                }
206
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
207
0
                            }
208
0
                        } else {
209
0
                            (*charsRequired) += charsToWrite + 1;
210
0
                        }
211
0
                    }
212
213
                    /* Host */
214
0
                    if (uri->hostData.ip4 != NULL) {
215
                        /* IPv4 */
216
0
                        int i = 0;
217
0
                        for (; i < 4; i++) {
218
0
                            const unsigned char value = uri->hostData.ip4->data[i];
219
0
                            const int charsToWrite =
220
0
                                (value > 99) ? 3 : ((value > 9) ? 2 : 1);
221
0
                            if (dest != NULL) {
222
0
                                if (written + charsToWrite <= maxChars) {
223
0
                                    URI_CHAR text[4];
224
0
                                    if (value > 99) {
225
0
                                        text[0] = _UT('0') + (value / 100);
226
0
                                        text[1] = _UT('0') + ((value % 100) / 10);
227
0
                                        text[2] = _UT('0') + (value % 10);
228
0
                                    } else if (value > 9) {
229
0
                                        text[0] = _UT('0') + (value / 10);
230
0
                                        text[1] = _UT('0') + (value % 10);
231
0
                                    } else {
232
0
                                        text[0] = _UT('0') + value;
233
0
                                    }
234
0
                                    text[charsToWrite] = _UT('\0');
235
0
                                    memcpy(dest + written, text,
236
0
                                           charsToWrite * sizeof(URI_CHAR));
237
0
                                    written += charsToWrite;
238
0
                                } else {
239
0
                                    dest[0] = _UT('\0');
240
0
                                    if (charsWritten != NULL) {
241
0
                                        *charsWritten = 0;
242
0
                                    }
243
0
                                    return URI_ERROR_TOSTRING_TOO_LONG;
244
0
                                }
245
0
                                if (i < 3) {
246
0
                                    if (written + 1 <= maxChars) {
247
0
                                        memcpy(dest + written, _UT("."),
248
0
                                               1 * sizeof(URI_CHAR));
249
0
                                        written += 1;
250
0
                                    } else {
251
0
                                        dest[0] = _UT('\0');
252
0
                                        if (charsWritten != NULL) {
253
0
                                            *charsWritten = 0;
254
0
                                        }
255
0
                                        return URI_ERROR_TOSTRING_TOO_LONG;
256
0
                                    }
257
0
                                }
258
0
                            } else {
259
0
                                (*charsRequired) += charsToWrite + ((i == 3) ? 0 : 1);
260
0
                            }
261
0
                        }
262
0
                    } else if (uri->hostData.ip6 != NULL) {
263
                        /* IPv6 */
264
0
                        int i = 0;
265
0
                        if (dest != NULL) {
266
0
                            if (written + 1 <= maxChars) {
267
0
                                memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR));
268
0
                                written += 1;
269
0
                            } else {
270
0
                                dest[0] = _UT('\0');
271
0
                                if (charsWritten != NULL) {
272
0
                                    *charsWritten = 0;
273
0
                                }
274
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
275
0
                            }
276
0
                        } else {
277
0
                            (*charsRequired) += 1;
278
0
                        }
279
280
0
                        for (; i < 16; i++) {
281
0
                            const unsigned char value = uri->hostData.ip6->data[i];
282
0
                            if (dest != NULL) {
283
0
                                if (written + 2 <= maxChars) {
284
0
                                    URI_CHAR text[3];
285
0
                                    text[0] =
286
0
                                        URI_FUNC(HexToLetterEx)(value / 16, URI_FALSE);
287
0
                                    text[1] =
288
0
                                        URI_FUNC(HexToLetterEx)(value % 16, URI_FALSE);
289
0
                                    text[2] = _UT('\0');
290
0
                                    memcpy(dest + written, text, 2 * sizeof(URI_CHAR));
291
0
                                    written += 2;
292
0
                                } else {
293
0
                                    dest[0] = _UT('\0');
294
0
                                    if (charsWritten != NULL) {
295
0
                                        *charsWritten = 0;
296
0
                                    }
297
0
                                    return URI_ERROR_TOSTRING_TOO_LONG;
298
0
                                }
299
0
                            } else {
300
0
                                (*charsRequired) += 2;
301
0
                            }
302
0
                            if (((i & 1) == 1) && (i < 15)) {
303
0
                                if (dest != NULL) {
304
0
                                    if (written + 1 <= maxChars) {
305
0
                                        memcpy(dest + written, _UT(":"),
306
0
                                               1 * sizeof(URI_CHAR));
307
0
                                        written += 1;
308
0
                                    } else {
309
0
                                        dest[0] = _UT('\0');
310
0
                                        if (charsWritten != NULL) {
311
0
                                            *charsWritten = 0;
312
0
                                        }
313
0
                                        return URI_ERROR_TOSTRING_TOO_LONG;
314
0
                                    }
315
0
                                } else {
316
0
                                    (*charsRequired) += 1;
317
0
                                }
318
0
                            }
319
0
                        }
320
321
0
                        if (dest != NULL) {
322
0
                            if (written + 1 <= maxChars) {
323
0
                                memcpy(dest + written, _UT("]"), 1 * sizeof(URI_CHAR));
324
0
                                written += 1;
325
0
                            } else {
326
0
                                dest[0] = _UT('\0');
327
0
                                if (charsWritten != NULL) {
328
0
                                    *charsWritten = 0;
329
0
                                }
330
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
331
0
                            }
332
0
                        } else {
333
0
                            (*charsRequired) += 1;
334
0
                        }
335
0
                    } else if (uri->hostData.ipFuture.first != NULL) {
336
                        /* IPvFuture */
337
0
                        const int charsToWrite = (int)(uri->hostData.ipFuture.afterLast
338
0
                                                       - uri->hostData.ipFuture.first);
339
0
                        if (dest != NULL) {
340
0
                            if (written + 1 <= maxChars) {
341
0
                                memcpy(dest + written, _UT("["), 1 * sizeof(URI_CHAR));
342
0
                                written += 1;
343
0
                            } else {
344
0
                                dest[0] = _UT('\0');
345
0
                                if (charsWritten != NULL) {
346
0
                                    *charsWritten = 0;
347
0
                                }
348
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
349
0
                            }
350
351
0
                            if (written + charsToWrite <= maxChars) {
352
0
                                memcpy(dest + written, uri->hostData.ipFuture.first,
353
0
                                       charsToWrite * sizeof(URI_CHAR));
354
0
                                written += charsToWrite;
355
0
                            } else {
356
0
                                dest[0] = _UT('\0');
357
0
                                if (charsWritten != NULL) {
358
0
                                    *charsWritten = 0;
359
0
                                }
360
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
361
0
                            }
362
363
0
                            if (written + 1 <= maxChars) {
364
0
                                memcpy(dest + written, _UT("]"), 1 * sizeof(URI_CHAR));
365
0
                                written += 1;
366
0
                            } else {
367
0
                                dest[0] = _UT('\0');
368
0
                                if (charsWritten != NULL) {
369
0
                                    *charsWritten = 0;
370
0
                                }
371
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
372
0
                            }
373
0
                        } else {
374
0
                            (*charsRequired) += 1 + charsToWrite + 1;
375
0
                        }
376
0
                    } else if (uri->hostText.first != NULL) {
377
                        /* Regname */
378
0
                        const int charsToWrite =
379
0
                            (int)(uri->hostText.afterLast - uri->hostText.first);
380
0
                        if (dest != NULL) {
381
0
                            if (written + charsToWrite <= maxChars) {
382
0
                                memcpy(dest + written, uri->hostText.first,
383
0
                                       charsToWrite * sizeof(URI_CHAR));
384
0
                                written += charsToWrite;
385
0
                            } else {
386
0
                                dest[0] = _UT('\0');
387
0
                                if (charsWritten != NULL) {
388
0
                                    *charsWritten = 0;
389
0
                                }
390
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
391
0
                            }
392
0
                        } else {
393
0
                            (*charsRequired) += charsToWrite;
394
0
                        }
395
0
                    }
396
397
                    /* Port */
398
0
                    if (uri->portText.first != NULL) {
399
0
                        const int charsToWrite =
400
0
                            (int)(uri->portText.afterLast - uri->portText.first);
401
0
                        if (dest != NULL) {
402
                            /* Leading ':' */
403
0
                            if (written + 1 <= maxChars) {
404
0
                                memcpy(dest + written, _UT(":"), 1 * sizeof(URI_CHAR));
405
0
                                written += 1;
406
0
                            } else {
407
0
                                dest[0] = _UT('\0');
408
0
                                if (charsWritten != NULL) {
409
0
                                    *charsWritten = 0;
410
0
                                }
411
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
412
0
                            }
413
414
                            /* Port number */
415
0
                            if (written + charsToWrite <= maxChars) {
416
0
                                memcpy(dest + written, uri->portText.first,
417
0
                                       charsToWrite * sizeof(URI_CHAR));
418
0
                                written += charsToWrite;
419
0
                            } else {
420
0
                                dest[0] = _UT('\0');
421
0
                                if (charsWritten != NULL) {
422
0
                                    *charsWritten = 0;
423
0
                                }
424
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
425
0
                            }
426
0
                        } else {
427
0
                            (*charsRequired) += 1 + charsToWrite;
428
0
                        }
429
0
                    }
430
                    /* clang-format off */
431
    /* [09/19] endif; */
432
                    /* clang-format on */
433
0
                }
434
                /* clang-format off */
435
    /* [10/19] append path to result; */
436
                /* clang-format on */
437
                /* Slash needed here? */
438
0
                if (uri->absolutePath
439
0
                    || ((uri->pathHead != NULL) && URI_FUNC(HasHost)(uri))) {
440
0
                    if (dest != NULL) {
441
0
                        if (written + 1 <= maxChars) {
442
0
                            memcpy(dest + written, _UT("/"), 1 * sizeof(URI_CHAR));
443
0
                            written += 1;
444
0
                        } else {
445
0
                            dest[0] = _UT('\0');
446
0
                            if (charsWritten != NULL) {
447
0
                                *charsWritten = 0;
448
0
                            }
449
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
450
0
                        }
451
0
                    } else {
452
0
                        (*charsRequired) += 1;
453
0
                    }
454
0
                }
455
456
0
                if (uri->pathHead != NULL) {
457
0
                    URI_TYPE(PathSegment) * walker = uri->pathHead;
458
0
                    do {
459
0
                        const int charsToWrite =
460
0
                            (int)(walker->text.afterLast - walker->text.first);
461
0
                        if (dest != NULL) {
462
0
                            if (written + charsToWrite <= maxChars) {
463
0
                                memcpy(dest + written, walker->text.first,
464
0
                                       charsToWrite * sizeof(URI_CHAR));
465
0
                                written += charsToWrite;
466
0
                            } else {
467
0
                                dest[0] = _UT('\0');
468
0
                                if (charsWritten != NULL) {
469
0
                                    *charsWritten = 0;
470
0
                                }
471
0
                                return URI_ERROR_TOSTRING_TOO_LONG;
472
0
                            }
473
0
                        } else {
474
0
                            (*charsRequired) += charsToWrite;
475
0
                        }
476
477
                        /* Not last segment -> append slash */
478
0
                        if (walker->next != NULL) {
479
0
                            if (dest != NULL) {
480
0
                                if (written + 1 <= maxChars) {
481
0
                                    memcpy(dest + written, _UT("/"),
482
0
                                           1 * sizeof(URI_CHAR));
483
0
                                    written += 1;
484
0
                                } else {
485
0
                                    dest[0] = _UT('\0');
486
0
                                    if (charsWritten != NULL) {
487
0
                                        *charsWritten = 0;
488
0
                                    }
489
0
                                    return URI_ERROR_TOSTRING_TOO_LONG;
490
0
                                }
491
0
                            } else {
492
0
                                (*charsRequired) += 1;
493
0
                            }
494
0
                        }
495
496
0
                        walker = walker->next;
497
0
                    } while (walker != NULL);
498
0
                }
499
                /* clang-format off */
500
    /* [11/19] if defined(query) then */
501
                /* clang-format on */
502
0
                if (uri->query.first != NULL) {
503
                    /* clang-format off */
504
    /* [12/19]     append "?" to result; */
505
                    /* clang-format on */
506
0
                    if (dest != NULL) {
507
0
                        if (written + 1 <= maxChars) {
508
0
                            memcpy(dest + written, _UT("?"), 1 * sizeof(URI_CHAR));
509
0
                            written += 1;
510
0
                        } else {
511
0
                            dest[0] = _UT('\0');
512
0
                            if (charsWritten != NULL) {
513
0
                                *charsWritten = 0;
514
0
                            }
515
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
516
0
                        }
517
0
                    } else {
518
0
                        (*charsRequired) += 1;
519
0
                    }
520
                    /* clang-format off */
521
    /* [13/19]     append query to result; */
522
                    /* clang-format on */
523
0
                    const int charsToWrite =
524
0
                        (int)(uri->query.afterLast - uri->query.first);
525
0
                    if (dest != NULL) {
526
0
                        if (written + charsToWrite <= maxChars) {
527
0
                            memcpy(dest + written, uri->query.first,
528
0
                                   charsToWrite * sizeof(URI_CHAR));
529
0
                            written += charsToWrite;
530
0
                        } else {
531
0
                            dest[0] = _UT('\0');
532
0
                            if (charsWritten != NULL) {
533
0
                                *charsWritten = 0;
534
0
                            }
535
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
536
0
                        }
537
0
                    } else {
538
0
                        (*charsRequired) += charsToWrite;
539
0
                    }
540
                    /* clang-format off */
541
    /* [14/19] endif; */
542
                    /* clang-format on */
543
0
                }
544
                /* clang-format off */
545
    /* [15/19] if defined(fragment) then */
546
                /* clang-format on */
547
0
                if (uri->fragment.first != NULL) {
548
                    /* clang-format off */
549
    /* [16/19]     append "#" to result; */
550
                    /* clang-format on */
551
0
                    if (dest != NULL) {
552
0
                        if (written + 1 <= maxChars) {
553
0
                            memcpy(dest + written, _UT("#"), 1 * sizeof(URI_CHAR));
554
0
                            written += 1;
555
0
                        } else {
556
0
                            dest[0] = _UT('\0');
557
0
                            if (charsWritten != NULL) {
558
0
                                *charsWritten = 0;
559
0
                            }
560
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
561
0
                        }
562
0
                    } else {
563
0
                        (*charsRequired) += 1;
564
0
                    }
565
                    /* clang-format off */
566
    /* [17/19]     append fragment to result; */
567
                    /* clang-format on */
568
0
                    const int charsToWrite =
569
0
                        (int)(uri->fragment.afterLast - uri->fragment.first);
570
0
                    if (dest != NULL) {
571
0
                        if (written + charsToWrite <= maxChars) {
572
0
                            memcpy(dest + written, uri->fragment.first,
573
0
                                   charsToWrite * sizeof(URI_CHAR));
574
0
                            written += charsToWrite;
575
0
                        } else {
576
0
                            dest[0] = _UT('\0');
577
0
                            if (charsWritten != NULL) {
578
0
                                *charsWritten = 0;
579
0
                            }
580
0
                            return URI_ERROR_TOSTRING_TOO_LONG;
581
0
                        }
582
0
                    } else {
583
0
                        (*charsRequired) += charsToWrite;
584
0
                    }
585
                    /* clang-format off */
586
    /* [18/19] endif; */
587
                    /* clang-format on */
588
0
                }
589
                /* clang-format off */
590
    /* [19/19] return result; */
591
                /* clang-format on */
592
0
                if (dest != NULL) {
593
0
                    dest[written++] = _UT('\0');
594
0
                    if (charsWritten != NULL) {
595
0
                        *charsWritten = written;
596
0
                    }
597
0
                }
598
0
                return URI_SUCCESS;
599
0
            }
600
0
        }
601
0
    }
602
0
}
Unexecuted instantiation: UriRecompose.c:uriToStringEngineA
Unexecuted instantiation: UriRecompose.c:uriToStringEngineW
603
604
#endif