• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* libcoap unit tests
2  *
3  * Copyright (C) 2012,2015,2022-2023 Olaf Bergmann <bergmann@tzi.org>
4  *
5  * SPDX-License-Identifier: BSD-2-Clause
6  *
7  * This file is part of the CoAP library libcoap. Please see
8  * README for terms of use.
9  */
10 
11 #include "test_common.h"
12 #include "test_uri.h"
13 
14 #include <stdio.h>
15 
16 static void
t_parse_uri1(void)17 t_parse_uri1(void) {
18   char teststr[] = "coap://[::1]/.well-known/core";
19 
20   int result;
21   coap_uri_t uri;
22 
23   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
24   if (result == 0) {
25     CU_ASSERT(uri.host.length == 3);
26     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3);
27 
28     CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
29 
30     CU_ASSERT(uri.path.length == 16);
31     CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
32 
33     CU_ASSERT(uri.query.length == 0);
34     CU_ASSERT(uri.query.s == NULL);
35   } else {
36     CU_FAIL("uri parser error");
37   }
38 }
39 
40 static void
t_parse_uri2(void)41 t_parse_uri2(void) {
42   char teststr[] = "coap://[::1]:8000/.well-known/core";
43   int result;
44   coap_uri_t uri;
45 
46   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
47   if (result == 0) {
48     CU_ASSERT(uri.host.length == 3);
49     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "::1", 3);
50 
51     CU_ASSERT(uri.port == 8000);
52 
53     CU_ASSERT(uri.path.length == 16);
54     CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
55 
56     CU_ASSERT(uri.query.length == 0);
57     CU_ASSERT(uri.query.s == NULL);
58   } else {
59     CU_FAIL("uri parser error");
60   }
61 }
62 
63 static void
t_parse_uri3(void)64 t_parse_uri3(void) {
65   char teststr[] = "coap://localhost/?foo&bla=fasel";
66   int result;
67   coap_uri_t uri;
68 
69   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
70   if (result == 0) {
71     CU_ASSERT(uri.host.length == 9);
72     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "localhost", 9);
73 
74     CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
75 
76     CU_ASSERT(uri.path.length == 0);
77 
78     CU_ASSERT(uri.query.length == 13);
79     CU_ASSERT_NSTRING_EQUAL(uri.query.s, "foo&bla=fasel", 13);
80   } else {
81     CU_FAIL("uri parser error");
82   }
83 }
84 
85 static void
t_parse_uri4(void)86 t_parse_uri4(void) {
87   char teststr[] = "coap://:100000";
88   int result;
89   coap_uri_t uri;
90 
91   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
92   CU_ASSERT(result < 0);
93 }
94 
95 static void
t_parse_uri5(void)96 t_parse_uri5(void) {
97   char teststr[] = "coap://foo:100000";
98   int result;
99   coap_uri_t uri;
100 
101   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
102   if (result == 0) {
103     CU_ASSERT(uri.host.length == 3);
104     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo", 3);
105 
106     CU_ASSERT(uri.path.length == 0);
107     CU_ASSERT(uri.path.s == NULL);
108 
109     CU_ASSERT(uri.query.length == 0);
110     CU_ASSERT(uri.query.s == NULL);
111 
112     CU_FAIL("invalid port not detected");
113   } else {
114     CU_PASS("detected invalid port");
115   }
116 }
117 
118 static void
t_parse_uri6(void)119 t_parse_uri6(void) {
120   char teststr[] = "coap://134.102.218.2/.well-known/core";
121   int result;
122   coap_uri_t uri;
123 
124   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
125   if (result == 0) {
126     CU_ASSERT(uri.host.length == 13);
127     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "134.102.218.2", 13);
128 
129     CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
130 
131     CU_ASSERT(uri.path.length == 16);
132     CU_ASSERT_NSTRING_EQUAL(uri.path.s, ".well-known/core", 16);
133 
134     CU_ASSERT(uri.query.length == 0);
135     CU_ASSERT(uri.query.s == NULL);
136   } else {
137     CU_FAIL("uri parser error");
138   }
139 }
140 
141 static void
t_parse_uri7(void)142 t_parse_uri7(void) {
143   char teststr[] = "coap://foo.bar:5683/some_resource/with/multiple/segments";
144   int result;
145   coap_uri_t uri;
146   unsigned char buf[40];
147   size_t buflen = sizeof(buf);
148 
149   /* The list of path segments to check against. Each segment is
150      preceded by a dummy option indicating that holds the (dummy)
151      delta value 0 and the actual segment length. */
152   const uint8_t checkbuf[] = {
153     0x0d, 0x00, 's', 'o', 'm', 'e', '_', 'r', 'e', 's', 'o', 'u', 'r', 'c', 'e',
154     0x04, 'w', 'i', 't', 'h',
155     0x08, 'm', 'u', 'l', 't', 'i', 'p', 'l', 'e',
156     0x08, 's', 'e', 'g', 'm', 'e', 'n', 't', 's'
157   };
158 
159   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
160   if (result == 0) {
161     CU_ASSERT(uri.host.length == 7);
162     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "foo.bar", 7);
163 
164     CU_ASSERT(uri.port == 5683);
165 
166     CU_ASSERT(uri.path.length == 36);
167     CU_ASSERT_NSTRING_EQUAL(uri.path.s, "some_resource/with/multiple/segments", 36);
168 
169     CU_ASSERT(uri.query.length == 0);
170     CU_ASSERT(uri.query.s == NULL);
171 
172     /* check path segments */
173     result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
174     CU_ASSERT(result == 4);
175     CU_ASSERT(buflen == sizeof(checkbuf));
176     CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen);
177   } else {
178     CU_FAIL("uri parser error");
179   }
180 }
181 
182 static void
t_parse_uri8(void)183 t_parse_uri8(void) {
184   coap_log_t level = coap_get_log_level();
185   char teststr[] = "http://example.com/%7E%AB%13";
186   int result;
187   coap_uri_t uri;
188 
189   coap_set_log_level(COAP_LOG_CRIT);
190   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
191   coap_set_log_level(level);
192   if (result < 0) {
193     CU_PASS("detected non-coap URI");
194   } else {
195     CU_FAIL("non-coap URI not recognized");
196   }
197 }
198 
199 static void
t_parse_uri9(void)200 t_parse_uri9(void) {
201   coap_log_t level = coap_get_log_level();
202   char teststr[] = "http://example.com/%x";
203   int result;
204   coap_uri_t uri;
205 
206   coap_set_log_level(COAP_LOG_CRIT);
207   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
208   coap_set_log_level(level);
209   if (result < 0) {
210     CU_PASS("detected non-coap URI");
211   } else {
212     CU_FAIL("non-coap URI not recognized");
213   }
214 }
215 
216 static void
t_parse_uri10(void)217 t_parse_uri10(void) {
218   char teststr[] = "/absolute/path";
219   int result;
220   coap_uri_t uri;
221 
222   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
223   if (result == 0) {
224     CU_ASSERT(uri.host.length == 0);
225     CU_ASSERT(uri.host.s == NULL);
226 
227     CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
228 
229     CU_ASSERT(uri.path.length == 13);
230     CU_ASSERT_NSTRING_EQUAL(uri.path.s, "absolute/path", 13);
231 
232     CU_ASSERT(uri.query.length == 0);
233     CU_ASSERT(uri.query.s == NULL);
234   } else {
235     CU_FAIL("uri parser error");
236   }
237 }
238 
239 static void
t_parse_uri11(void)240 t_parse_uri11(void) {
241   char teststr[] =
242       "coap://xn--18j4d.example/%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF";
243   int result;
244   coap_uri_t uri;
245   unsigned char buf[40];
246   size_t buflen = sizeof(buf);
247 
248   /* The list of path segments to check against. Each segment is
249      preceded by a dummy option indicating that holds the (dummy)
250      delta value 0 and the actual segment length. */
251   const uint8_t checkbuf[] = {
252     0x0d, 0x02, 0xE3, 0x81, 0x93, 0xE3, 0x82, 0x93,
253     0xE3, 0x81, 0xAB, 0xE3, 0x81, 0xA1, 0xE3, 0x81,
254     0xAF
255   };
256 
257   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
258   if (result == 0) {
259     CU_ASSERT(uri.host.length == 17);
260     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "xn--18j4d.example", 17);
261 
262     CU_ASSERT(uri.port == COAP_DEFAULT_PORT);
263 
264     CU_ASSERT(uri.path.length == 45);
265     CU_ASSERT_NSTRING_EQUAL(uri.path.s,
266                             "%E3%81%93%E3%82%93%E3%81%AB%E3%81%A1%E3%81%AF", 45);
267 
268     CU_ASSERT(uri.query.length == 0);
269     CU_ASSERT(uri.query.s == NULL);
270 
271     /* check path segments */
272     result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
273     CU_ASSERT(result == 1);
274     CU_ASSERT(buflen == sizeof(checkbuf));
275     CU_ASSERT_NSTRING_EQUAL(buf, checkbuf, buflen);
276   } else {
277     CU_FAIL("uri parser error");
278   }
279 }
280 
281 static void
t_parse_uri12(void)282 t_parse_uri12(void) {
283   char teststr[] = "coap://198.51.100.1:61616//%2F//?%2F%2F&?%26";
284   int result;
285   coap_uri_t uri;
286   unsigned char buf[40];
287   size_t buflen = sizeof(buf);
288 
289   /* The list of path segments to check against. Each segment is
290      preceded by a dummy option indicating that holds the (dummy)
291      delta value 0 and the actual segment length. */
292   const uint8_t uricheckbuf[] = { 0x00, 0x01, 0x2f, 0x00, 0x00 };
293   const uint8_t querycheckbuf[] = { 0x02, 0x2f, 0x2f, 0x02, 0x3f, 0x26 };
294 
295   result = coap_split_uri((unsigned char *)teststr, strlen(teststr), &uri);
296   if (result == 0) {
297     CU_ASSERT(uri.host.length == 12);
298     CU_ASSERT_NSTRING_EQUAL(uri.host.s, "198.51.100.1", 12);
299 
300     CU_ASSERT(uri.port == 61616);
301 
302     CU_ASSERT(uri.path.length == 6);
303     CU_ASSERT_NSTRING_EQUAL(uri.path.s, "/%2F//", 6);
304 
305     CU_ASSERT(uri.query.length == 11);
306     CU_ASSERT_NSTRING_EQUAL(uri.query.s, "%2F%2F&?%26", 11);
307 
308     /* check path segments */
309     result = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
310     CU_ASSERT(result == 4);
311     CU_ASSERT(buflen == sizeof(uricheckbuf));
312     CU_ASSERT_NSTRING_EQUAL(buf, uricheckbuf, buflen);
313 
314     /* check query segments */
315     buflen = sizeof(buf);
316     result = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
317     CU_ASSERT(result == 2);
318     CU_ASSERT(buflen == sizeof(querycheckbuf));
319     CU_ASSERT_NSTRING_EQUAL(buf, querycheckbuf, buflen);
320   } else {
321     CU_FAIL("uri parser error");
322   }
323 }
324 
325 #ifdef _MSC_VER
326 #  define ALIGNED(x)
327 #else
328 #  define ALIGNED(x) __attribute__ ((aligned (x)))
329 #endif
330 
331 static void
t_parse_uri13(void)332 t_parse_uri13(void) {
333   uint8_t teststr[] ALIGNED(8) = {
334     0x80, 0x03, 'f',  'o',
335     'o',  0x3b, '.',  'w',  'e',  'l',  'l',  '-',
336     'k',  'n',  'o',  'w',  'n',  0x04,  'c', 'o',
337     'r',  'e'
338   };
339 
340   coap_pdu_t pdu = {
341     .max_size = sizeof(teststr),
342     .e_token_length = 0,
343     .token = teststr,
344     .used_size = sizeof(teststr)
345   };
346 
347   coap_string_t *uri_path = coap_get_uri_path(&pdu);
348 
349   CU_ASSERT(uri_path->length == sizeof(COAP_DEFAULT_URI_WELLKNOWN)-1);
350   CU_ASSERT_NSTRING_EQUAL(uri_path->s, COAP_DEFAULT_URI_WELLKNOWN,
351                           sizeof(COAP_DEFAULT_URI_WELLKNOWN)-1);
352   coap_delete_string(uri_path);
353 }
354 
355 static void
t_parse_uri14(void)356 t_parse_uri14(void) {
357   char teststr[] =
358       "longerthan13lessthan270=0123456789012345678901234567890123456789";
359   int result;
360 
361   /* buf is large enough to hold sizeof(teststr) - 1 bytes content and
362    * 2 bytes for the option header. */
363   unsigned char buf[sizeof(teststr) + 1];
364   size_t buflen = sizeof(buf);
365 
366   result = coap_split_query((unsigned char *)teststr, strlen(teststr),
367                             buf, &buflen);
368   if (result >= 0) {
369     CU_ASSERT(buf[0] == 0x0d);
370     CU_ASSERT(buf[1] == strlen(teststr) - 13);
371 
372     CU_ASSERT_NSTRING_EQUAL(buf+2, teststr, strlen(teststr));
373   } else {
374     CU_FAIL("uri parser error");
375   }
376 }
377 
378 static void
t_parse_uri15(void)379 t_parse_uri15(void) {
380   char teststr[] =
381       "longerthan13lessthan270=0123456789012345678901234567890123456789";
382   int result;
383 
384   /* buf is too small to hold sizeof(teststr) - 1 bytes content and 2
385    * bytes for the option header. */
386   unsigned char buf[sizeof(teststr) - 1];
387   size_t buflen = sizeof(buf);
388 
389   result = coap_split_query((unsigned char *)teststr, strlen(teststr),
390                             buf, &buflen);
391   CU_ASSERT(result == 0);
392 }
393 
394 static void
t_parse_uri16(void)395 t_parse_uri16(void) {
396   char teststr[] =
397       "longerthan13lessthan270=0123456789012345678901234567890123456789";
398   int result;
399 
400   /* buf is too small to hold the option header. */
401   unsigned char buf[1];
402   size_t buflen = sizeof(buf);
403 
404   result = coap_split_query((unsigned char *)teststr, strlen(teststr),
405                             buf, &buflen);
406   CU_ASSERT(result == 0);
407 }
408 
409 static void
t_parse_uri17(void)410 t_parse_uri17(void) {
411   char teststr[] =
412       "thisislongerthan269="
413       "01234567890123456789012345678901234567890123456789"
414       "01234567890123456789012345678901234567890123456789"
415       "01234567890123456789012345678901234567890123456789"
416       "01234567890123456789012345678901234567890123456789"
417       "01234567890123456789012345678901234567890123456789";
418   int result;
419 
420   /* buf is large enough to hold sizeof(teststr) - 1 bytes content and
421    * 3 bytes for the option header. */
422   unsigned char buf[sizeof(teststr) + 2];
423   size_t buflen = sizeof(buf);
424 
425   result = coap_split_query((unsigned char *)teststr, strlen(teststr),
426                             buf, &buflen);
427   if (result >= 0) {
428     CU_ASSERT(buf[0] == 0x0e);
429     CU_ASSERT(buf[1] == (((strlen(teststr) - 269) >> 8) & 0xff));
430     CU_ASSERT(buf[2] == ((strlen(teststr) - 269) & 0xff));
431 
432     CU_ASSERT_NSTRING_EQUAL(buf+3, teststr, strlen(teststr));
433   } else {
434     CU_FAIL("uri parser error");
435   }
436 }
437 
438 static void
t_parse_uri18(void)439 t_parse_uri18(void) {
440   uint8_t token[1] = "";
441   coap_pdu_t pdu = {
442     .max_size = 0,
443     .e_token_length = 0,
444     .token = token,
445     .used_size = 0
446   };
447 
448   coap_string_t *uri_path = coap_get_uri_path(&pdu);
449 
450   CU_ASSERT(uri_path->length == 0);
451 #if 0
452   /* Currently this is not the case - Issue #167 */
453   /* strings are stored with terminating zero */
454   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "", 1);
455 #endif
456   coap_delete_string(uri_path);
457 }
458 
459 static void
t_parse_uri19(void)460 t_parse_uri19(void) {
461   uint8_t teststr[] ALIGNED(8) = {
462     0xb3, 'f', 'o', 'o',
463     0x00                  /* "foo/" as Uri-Path options */
464   };
465 
466   coap_pdu_t pdu = {
467     .max_size = sizeof(teststr),
468     .e_token_length = 0,
469     .token = teststr,
470     .used_size = sizeof(teststr)
471   };
472 
473   coap_string_t *uri_path = coap_get_uri_path(&pdu);
474 
475   CU_ASSERT(uri_path->length == 4);
476   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "foo/", 4);
477   coap_delete_string(uri_path);
478 }
479 
480 static void
t_parse_uri20(void)481 t_parse_uri20(void) {
482   uint8_t teststr[] ALIGNED(8) = {
483     0xb0, 0x00                  /* "//" as Uri-Path options */
484   };
485 
486   coap_pdu_t pdu = {
487     .max_size = sizeof(teststr),
488     .e_token_length = 0,
489     .token = teststr,
490     .used_size = sizeof(teststr)
491   };
492 
493   coap_string_t *uri_path = coap_get_uri_path(&pdu);
494 
495   /* The leading '/' is stripped hence only one '/' remains. */
496   CU_ASSERT(uri_path->length == 1);
497   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "/", 1);
498   coap_delete_string(uri_path);
499 }
500 
501 static void
t_parse_uri21(void)502 t_parse_uri21(void) {
503   uint8_t teststr[] ALIGNED(8) = {
504     0xb0, 0x03, 'f', 'o', 'o'   /* "//foo" as Uri-Path options */
505   };
506 
507   coap_pdu_t pdu = {
508     .max_size = sizeof(teststr),
509     .e_token_length = 0,
510     .token = teststr,
511     .used_size = sizeof(teststr)
512   };
513 
514   coap_string_t *uri_path = coap_get_uri_path(&pdu);
515 
516   /* The leading '/' is stripped hence only one '/' remains. */
517   CU_ASSERT(uri_path->length == 4);
518   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "/foo", 4);
519   coap_delete_string(uri_path);
520 }
521 
522 static void
t_parse_uri22(void)523 t_parse_uri22(void) {
524   uint8_t teststr[] ALIGNED(8) = {
525     /* characters that are not percent-encoded in a path segment */
526     0xba, '-', '.', '_', '~', '!', '$', '&', '\'', '(', ')',
527     0x05, '*', '+', ',', ';', '='
528   };
529 
530   coap_pdu_t pdu = {
531     .max_size = sizeof(teststr),
532     .e_token_length = 0,
533     .token = teststr,
534     .used_size = sizeof(teststr)
535   };
536 
537   coap_string_t *uri_path = coap_get_uri_path(&pdu);
538 
539   CU_ASSERT(uri_path->length == 16);
540   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "-._~!$&'()/*+,;=", 16);
541   coap_delete_string(uri_path);
542 }
543 
544 static void
t_parse_uri23(void)545 t_parse_uri23(void) {
546   uint8_t teststr[] ALIGNED(8) = {
547     /* characters that must be percent-encoded in a path segment */
548     0xb5, '%', ' ', '#', '[', ']'
549   };
550 
551   coap_pdu_t pdu = {
552     .max_size = sizeof(teststr),
553     .e_token_length = 0,
554     .token = teststr,
555     .used_size = sizeof(teststr)
556   };
557 
558   coap_string_t *uri_path = coap_get_uri_path(&pdu);
559 
560   CU_ASSERT(uri_path->length == 15);
561   CU_ASSERT_NSTRING_EQUAL(uri_path->s, "%25%20%23%5B%5D", 15);
562   coap_delete_string(uri_path);
563 }
564 
565 /*
566  * To test Issue #212 which reads off the end of the input buffer when looking
567  * for . or .. in the path.
568  * Credit to OSS-Fuzz for finding this, work done by Bhargava Shastry
569  */
570 static void
t_parse_uri24(void)571 t_parse_uri24(void) {
572   /* coap://\206cap:// */
573   uint8_t teststr[] = { 0x63, 0x6f, 0x61, 0x70, 0x3a, 0x2f, 0x2f, 0x86, 0x63, 0x6f, 0x61, 0x70, 0x3a, 0x2f, 0x2f };
574   int result;
575   unsigned char buf[40];
576   size_t buflen = sizeof(buf);
577 
578   result = coap_split_path(teststr, sizeof(teststr), buf, &buflen);
579   CU_ASSERT(result == 5);
580   CU_ASSERT(buflen == 16);
581 }
582 
583 
584 CU_pSuite
t_init_uri_tests(void)585 t_init_uri_tests(void) {
586   CU_pSuite suite;
587 
588   suite = CU_add_suite("uri parser", NULL, NULL);
589   if (!suite) {                        /* signal error */
590     fprintf(stderr, "W: cannot add uri parser test suite (%s)\n",
591             CU_get_error_msg());
592 
593     return NULL;
594   }
595 
596 #define URI_TEST(s,t)                                                      \
597   if (!CU_ADD_TEST(s,t)) {                                              \
598     fprintf(stderr, "W: cannot add uri parser test (%s)\n",              \
599             CU_get_error_msg());                                      \
600   }
601 
602   URI_TEST(suite, t_parse_uri1);
603   URI_TEST(suite, t_parse_uri2);
604   URI_TEST(suite, t_parse_uri3);
605   URI_TEST(suite, t_parse_uri4);
606   URI_TEST(suite, t_parse_uri5);
607   URI_TEST(suite, t_parse_uri6);
608   URI_TEST(suite, t_parse_uri7);
609   URI_TEST(suite, t_parse_uri8);
610   URI_TEST(suite, t_parse_uri9);
611   URI_TEST(suite, t_parse_uri10);
612   URI_TEST(suite, t_parse_uri11);
613   URI_TEST(suite, t_parse_uri12);
614   URI_TEST(suite, t_parse_uri13);
615   URI_TEST(suite, t_parse_uri14);
616   URI_TEST(suite, t_parse_uri15);
617   URI_TEST(suite, t_parse_uri16);
618   URI_TEST(suite, t_parse_uri17);
619   URI_TEST(suite, t_parse_uri18);
620   URI_TEST(suite, t_parse_uri19);
621   URI_TEST(suite, t_parse_uri20);
622   URI_TEST(suite, t_parse_uri21);
623   URI_TEST(suite, t_parse_uri22);
624   URI_TEST(suite, t_parse_uri23);
625   URI_TEST(suite, t_parse_uri24);
626 
627   return suite;
628 }
629