iPXE
uri_test.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2014 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /** @file
27  *
28  * URI self-tests
29  *
30  */
31 
32 /* Forcibly enable assertions */
33 #undef NDEBUG
34 
35 #include <string.h>
36 #include <byteswap.h>
37 #include <ipxe/uri.h>
38 #include <ipxe/tcpip.h>
39 #include <ipxe/params.h>
40 #include <ipxe/test.h>
41 
42 /** A URI parsing/formatting test */
43 struct uri_test {
44  /** URI string */
45  const char *string;
46  /** URI */
47  struct uri uri;
48 };
49 
50 /** A URI port number test */
51 struct uri_port_test {
52  /** URI string */
53  const char *string;
54  /** Default port number */
55  unsigned int default_port;
56  /** Expected port number */
57  unsigned int port;
58 };
59 
60 /** A URI or path resolution test */
62  /** Base path or URI */
63  const char *base;
64  /** Relative path or URI */
65  const char *relative;
66  /** Expected resolved path or URI */
67  const char *resolved;
68 };
69 
70 /** A PXE URI test */
71 struct uri_pxe_test {
72  /** Server address */
73  union {
74  struct sockaddr sa;
75  struct sockaddr_in sin;
78  } server;
79  /** Filename */
80  const char *filename;
81  /** URI */
82  struct uri uri;
83  /** URI string (for display only; cannot be reparsed) */
84  const char *string;
85 };
86 
87 /** A current working URI test */
89  /** Relative URI */
90  const char *relative;
91  /** Expected new working URI */
92  const char *expected;
93 };
94 
95 /** A form parameter URI test list */
97  /** Key */
98  const char *key;
99  /** Value */
100  const char *value;
101 };
102 
103 /** A form parameter URI test */
105  /** URI string */
106  const char *string;
107  /** URI */
108  struct uri uri;
109  /** Parameter list name */
110  const char *name;
111  /** Parameter list */
113 };
114 
115 /**
116  * Compare two URI component strings
117  *
118  * @v first First string, or NULL
119  * @v second Second string, or NULL
120  * @v difference Difference
121  */
122 static int uristrcmp ( const char *first, const char *second ) {
123 
124  /* Compare strings, allowing for either to be NULL */
125  if ( first == second ) {
126  return 0;
127  } else if ( ( first == NULL ) || ( second == NULL ) ) {
128  return -1;
129  } else {
130  return strcmp ( first, second );
131  }
132 }
133 
134 /**
135  * Report URI equality test result
136  *
137  * @v uri URI
138  * @v expected Expected URI
139  * @v file Test code file
140  * @v line Test code line
141  */
142 static void uri_okx ( struct uri *uri, struct uri *expected, const char *file,
143  unsigned int line ) {
144 
145  okx ( uristrcmp ( uri->scheme, expected->scheme ) == 0, file, line );
146  okx ( uristrcmp ( uri->opaque, expected->opaque ) == 0, file, line );
147  okx ( uristrcmp ( uri->user, expected->user ) == 0, file, line );
148  okx ( uristrcmp ( uri->password, expected->password ) == 0, file, line);
149  okx ( uristrcmp ( uri->host, expected->host ) == 0, file, line );
150  okx ( uristrcmp ( uri->port, expected->port ) == 0, file, line );
151  okx ( uristrcmp ( uri->path, expected->path ) == 0, file, line );
152  okx ( uristrcmp ( uri->epath, expected->epath ) == 0, file, line );
153  okx ( uristrcmp ( uri->equery, expected->equery ) == 0, file, line );
154  okx ( uristrcmp ( uri->efragment, expected->efragment ) == 0,
155  file, line);
156  okx ( uri->params == expected->params, file, line );
157 }
158 #define uri_ok( uri, expected ) uri_okx ( uri, expected, __FILE__, __LINE__ )
159 
160 /**
161  * Report URI parsing test result
162  *
163  * @v test URI test
164  * @v file Test code file
165  * @v line Test code line
166  */
167 static void uri_parse_okx ( struct uri_test *test, const char *file,
168  unsigned int line ) {
169  struct uri *uri;
170 
171  /* Parse URI */
172  uri = parse_uri ( test->string );
173  okx ( uri != NULL, file, line );
174  if ( uri )
175  uri_okx ( uri, &test->uri, file, line );
176  uri_put ( uri );
177 }
178 #define uri_parse_ok( test ) uri_parse_okx ( test, __FILE__, __LINE__ )
179 
180 /**
181  * Report URI formatting test result
182  *
183  * @v test URI test
184  * @v file Test code file
185  * @v line Test code line
186  */
187 static void uri_format_okx ( struct uri_test *test, const char *file,
188  unsigned int line ) {
189  char buf[ strlen ( test->string ) + 1 /* NUL */ ];
190  char *tmp;
191  size_t len;
192 
193  /* Format into fixed-size buffer */
194  len = format_uri ( &test->uri, buf, sizeof ( buf ) );
195  okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
196  okx ( strcmp ( buf, test->string ) == 0, file, line );
197 
198  /* Format into temporarily allocated buffer */
199  tmp = format_uri_alloc ( &test->uri );
200  okx ( tmp != NULL, file, line );
201  if ( tmp )
202  okx ( strcmp ( tmp, test->string ) == 0, file, line );
203  free ( tmp );
204 }
205 #define uri_format_ok( test ) uri_format_okx ( test, __FILE__, __LINE__ )
206 
207 /**
208  * Report URI duplication test result
209  *
210  * @v test URI
211  * @v file Test code file
212  * @v line Test code line
213  */
214 static void uri_dup_okx ( struct uri *uri, const char *file,
215  unsigned int line ) {
216  struct uri *dup;
217 
218  dup = uri_dup ( uri );
219  okx ( dup != NULL, file, line );
220  if ( dup )
221  uri_okx ( dup, uri, file, line );
222  uri_put ( dup );
223 }
224 #define uri_dup_ok( test ) uri_dup_okx ( test, __FILE__, __LINE__ )
225 
226 /**
227  * Report URI combined parsing and formatting test result
228  *
229  * @v test URI test
230  * @v file Test code file
231  * @v line Test code line
232  */
233 static void uri_parse_format_dup_okx ( struct uri_test *test, const char *file,
234  unsigned int line ) {
235 
236  uri_parse_okx ( test, file, line );
237  uri_format_okx ( test, file, line );
238  uri_dup_okx ( &test->uri, file, line );
239 }
240 #define uri_parse_format_dup_ok( test ) \
241  uri_parse_format_dup_okx ( test, __FILE__, __LINE__ )
242 
243 /**
244  * Report URI port number test result
245  *
246  * @v test URI port number test
247  * @v file Test code file
248  * @v line Test code line
249  */
250 static void uri_port_okx ( struct uri_port_test *test, const char *file,
251  unsigned int line ) {
252  struct uri *uri;
253  unsigned int port;
254 
255  /* Parse URI */
256  uri = parse_uri ( test->string );
257  okx ( uri != NULL, file, line );
258  if ( uri ) {
259  port = uri_port ( uri, test->default_port );
260  okx ( port == test->port, file, line );
261  }
262  uri_put ( uri );
263 }
264 #define uri_port_ok( test ) uri_port_okx ( test, __FILE__, __LINE__ )
265 
266 /**
267  * Report URI resolution test result
268  *
269  * @v test Path resolution test
270  * @v file Test code file
271  * @v line Test code line
272  */
273 static void uri_resolve_okx ( struct uri_resolve_test *test,
274  const char *file, unsigned int line ) {
275  struct uri *base;
276  struct uri *relative;
277  struct uri *resolved = NULL;
278  char *formatted;
279 
280  /* Parse URIs */
281  base = parse_uri ( test->base );
282  okx ( base != NULL, file, line );
283  relative = parse_uri ( test->relative );
284  okx ( relative != NULL, file, line );
285 
286  /* Resolve URI */
287  if ( base && relative ) {
288  resolved = resolve_uri ( base, relative );
289  okx ( resolved != NULL, file, line );
290  }
291 
292  /* Format resolved URI */
293  formatted = format_uri_alloc ( resolved );
294  okx ( formatted != NULL, file, line );
295 
296  /* Check resolved URI */
297  if ( formatted )
298  okx ( strcmp ( formatted, test->resolved ) == 0, file, line );
299 
300  free ( formatted );
301  uri_put ( resolved );
302  uri_put ( relative );
303  uri_put ( base );
304 }
305 #define uri_resolve_ok( test ) uri_resolve_okx ( test, __FILE__, __LINE__ )
306 
307 /**
308  * Report path resolution test result
309  *
310  * @v test Path resolution test
311  * @v file Test code file
312  * @v line Test code line
313  */
315  const char *file, unsigned int line ) {
316  char *resolved;
317 
318  /* Resolve paths using resolve_path() directly */
319  resolved = resolve_path ( test->base, test->relative );
320  okx ( resolved != NULL, file, line );
321  if ( resolved )
322  okx ( strcmp ( resolved, test->resolved ) == 0, file, line );
323  free ( resolved );
324 
325  /* Resolve paths as URIs (since all paths are valid URIs) */
326  uri_resolve_okx ( test, file, line );
327 }
328 #define uri_resolve_path_ok( test ) \
329  uri_resolve_path_okx ( test, __FILE__, __LINE__ )
330 
331 /**
332  * Report URI PXE test result
333  *
334  * @v test URI PXE test
335  * @v file Test code file
336  * @v line Test code line
337  */
338 static void uri_pxe_okx ( struct uri_pxe_test *test, const char *file,
339  unsigned int line ) {
340  char buf[ strlen ( test->string ) + 1 /* NUL */ ];
341  struct uri *uri;
342  size_t len;
343 
344  /* Construct URI */
345  uri = pxe_uri ( &test->server.sa, test->filename );
346  okx ( uri != NULL, file, line );
347  if ( uri ) {
348  uri_okx ( uri, &test->uri, file, line );
349  len = format_uri ( uri, buf, sizeof ( buf ) );
350  okx ( len == ( sizeof ( buf ) - 1 /* NUL */ ), file, line );
351  okx ( strcmp ( buf, test->string ) == 0, file, line );
352  }
353  uri_put ( uri );
354 }
355 #define uri_pxe_ok( test ) uri_pxe_okx ( test, __FILE__, __LINE__ )
356 
357 /**
358  * Report current working URI test result
359  *
360  * @v tests List of current working URI tests
361  * @v file Test code file
362  * @v line Test code line
363  */
364 static void uri_churi_okx ( struct uri_churi_test *test, const char *file,
365  unsigned int line ) {
366  struct uri *old_cwuri;
367  struct uri *uri;
368  char *formatted;
369 
370  /* Preserve original current working URI */
371  old_cwuri = uri_get ( cwuri );
372 
373  /* Perform sequence of current working URI changes */
374  do {
375  /* Parse relative URI */
376  uri = parse_uri ( test->relative );
377  okx ( uri != NULL, file, line );
378 
379  /* Move to this URI */
380  churi ( uri );
381 
382  /* Format new current working URI */
384  okx ( formatted != NULL, file, line );
385  if ( formatted ) {
386  okx ( strcmp ( formatted, test->expected ) == 0,
387  file, line );
388  }
389 
390  /* Free temporary storage */
391  free ( formatted );
392  uri_put ( uri );
393 
394  /* Move to next current working URI test */
395  test++;
396 
397  } while ( test->relative != NULL );
398 
399  /* Restore original current working URI */
400  churi ( old_cwuri );
401  uri_put ( old_cwuri );
402 }
403 #define uri_churi_ok( test ) uri_churi_okx ( test, __FILE__, __LINE__ )
404 
405 /**
406  * Report form parameter URI test list result
407  *
408  * @v test Form parameter URI test
409  * @v uri URI
410  * @v file Test code file
411  * @v line Test code line
412  */
414  struct uri *uri, const char *file,
415  unsigned int line ) {
416  struct uri_params_test_list *list;
417  struct parameter *param;
418 
419  /* Check URI */
420  uri_okx ( uri, &test->uri, file, line );
421 
422  /* Check URI parameters */
423  okx ( uri->params != NULL, file, line );
424  if ( uri->params ) {
425  list = test->list;
427  okx ( strcmp ( param->key, list->key ) == 0,
428  file, line );
429  okx ( strcmp ( param->value, list->value ) == 0,
430  file, line );
431  list++;
432  }
433  okx ( list->key == NULL, file, line );
434  }
435 }
436 #define uri_params_list_ok( test ) \
437  uri_params_list_okx ( test, __FILE__, __LINE__ )
438 
439 /**
440  * Report form parameter URI test result
441  *
442  * @v test Form parameter URI test
443  * @v file Test code file
444  * @v line Test code line
445  */
446 static void uri_params_okx ( struct uri_params_test *test, const char *file,
447  unsigned int line ) {
448  struct uri_params_test_list *list;
449  struct parameters *params;
450  struct parameter *param;
451  struct uri *uri;
452  struct uri *dup;
453 
454  /* Create parameter list */
455  params = create_parameters ( test->name );
456  okx ( params != NULL, file, line );
457  if ( params ) {
458  for ( list = test->list ; list->key ; list++ ) {
459  param = add_parameter ( params, list->key, list->value);
460  okx ( param != NULL, file, line );
461  }
462  }
463 
464  /* Record parameter list as part of expected URI */
465  test->uri.params = params;
466 
467  /* Parse URI */
468  uri = parse_uri ( test->string );
469  okx ( uri != NULL, file, line );
470  if ( uri )
471  uri_params_list_okx ( test, uri, file, line );
472 
473  /* Duplicate URI */
474  dup = uri_dup ( uri );
475  okx ( dup != NULL, file, line );
476  if ( dup )
477  uri_params_list_okx ( test, dup, file, line );
478 
479  /* Clear parameter list in expected URI */
480  test->uri.params = NULL;
481 
482  uri_put ( uri );
483  uri_put ( dup );
484 }
485 #define uri_params_ok( test ) uri_params_okx ( test, __FILE__, __LINE__ )
486 
487 /** Empty URI */
488 static struct uri_test uri_empty = {
489  .string = "",
490 };
491 
492 /** Basic HTTP URI */
493 static struct uri_test uri_boot_ipxe_org = {
494  "http://boot.ipxe.org/demo/boot.php",
495  { .scheme = "http", .host = "boot.ipxe.org",
496  .path = "/demo/boot.php", .epath = "/demo/boot.php" },
497 };
498 
499 /** Basic opaque URI */
500 static struct uri_test uri_mailto = {
501  "mailto:ipxe-devel@lists.ipxe.org",
502  { .scheme = "mailto", .opaque = "ipxe-devel@lists.ipxe.org" },
503 };
504 
505 /** Basic host-only URI */
506 static struct uri_test uri_host = {
507  "http://boot.ipxe.org",
508  { .scheme = "http", .host = "boot.ipxe.org" },
509 };
510 
511 /** Basic path-only URI */
512 static struct uri_test uri_path = {
513  "/var/lib/tftpboot/pxelinux.0",
514  { .path = "/var/lib/tftpboot/pxelinux.0",
515  .epath ="/var/lib/tftpboot/pxelinux.0" },
516 };
517 
518 /** Path-only URI with escaped characters */
519 static struct uri_test uri_path_escaped = {
520  "/hello%20world%3F",
521  { .path = "/hello world?", .epath = "/hello%20world%3F" },
522 };
523 
524 /** HTTP URI with all the trimmings */
525 static struct uri_test uri_http_all = {
526  "http://anon:password@example.com:3001/~foo/cgi-bin/foo.pl?a=b&c=d#bit",
527  {
528  .scheme = "http",
529  .user = "anon",
530  .password = "password",
531  .host = "example.com",
532  .port = "3001",
533  .path = "/~foo/cgi-bin/foo.pl",
534  .epath = "/~foo/cgi-bin/foo.pl",
535  .equery = "a=b&c=d",
536  .efragment = "bit",
537  },
538 };
539 
540 /** HTTP URI with escaped characters */
541 static struct uri_test uri_http_escaped = {
542  "https://test.ipxe.org/wtf%3F%0A?kind%23of/uri%20is#this%3F",
543  {
544  .scheme = "https",
545  .host = "test.ipxe.org",
546  .path = "/wtf?\n",
547  .epath = "/wtf%3F%0A",
548  .equery = "kind%23of/uri%20is",
549  .efragment = "this%3F",
550  },
551 };
552 
553 /** HTTP URI with improperly escaped characters */
555  /* We accept for parsing improperly escaped characters.
556  * (Formatting the parsed URI would produce the properly
557  * encoded form, and so would not exactly match the original
558  * URI string.)
559  */
560  "https://test%2eipxe.org/wt%66%3f\n?kind%23of/uri is#this?",
561  {
562  .scheme = "https",
563  .host = "test.ipxe.org",
564  .path = "/wtf?\n",
565  .epath = "/wt%66%3f\n",
566  .equery = "kind%23of/uri is",
567  .efragment = "this?",
568  },
569 };
570 
571 /** IPv6 URI */
572 static struct uri_test uri_ipv6 = {
573  "http://[2001:ba8:0:1d4::6950:5845]/",
574  {
575  .scheme = "http",
576  .host = "[2001:ba8:0:1d4::6950:5845]",
577  .path = "/",
578  .epath = "/",
579  },
580 };
581 
582 /** IPv6 URI with port */
583 static struct uri_test uri_ipv6_port = {
584  "http://[2001:ba8:0:1d4::6950:5845]:8001/boot",
585  {
586  .scheme = "http",
587  .host = "[2001:ba8:0:1d4::6950:5845]",
588  .port = "8001",
589  .path = "/boot",
590  .epath = "/boot",
591  },
592 };
593 
594 /** IPv6 URI with link-local address */
595 static struct uri_test uri_ipv6_local = {
596  "http://[fe80::69ff:fe50:5845%25net0]/ipxe",
597  {
598  .scheme = "http",
599  .host = "[fe80::69ff:fe50:5845%net0]",
600  .path = "/ipxe",
601  .epath = "/ipxe",
602  },
603 };
604 
605 /** IPv6 URI with link-local address not conforming to RFC 6874 */
607  /* We accept for parsing a single "%" in "%net0" (rather than
608  * the properly encoded form "%25net0"). (Formatting the
609  * parsed URI would produce the properly encoded form, and so
610  * would not exactly match the original URI string.)
611  */
612  "http://[fe80::69ff:fe50:5845%net0]/ipxe",
613  {
614  .scheme = "http",
615  .host = "[fe80::69ff:fe50:5845%net0]",
616  .path = "/ipxe",
617  .epath = "/ipxe",
618  },
619 };
620 
621 /** iSCSI URI */
622 static struct uri_test uri_iscsi = {
623  "iscsi:10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
624  {
625  .scheme = "iscsi",
626  .opaque = "10.253.253.1::::iqn.2010-04.org.ipxe:rabbit",
627  },
628 };
629 
630 /** File URI with relative (opaque) path */
631 static struct uri_test uri_file_relative = {
632  "file:boot/script.ipxe",
633  {
634  .scheme = "file",
635  .opaque = "boot/script.ipxe",
636  },
637 };
638 
639 /** File URI with absolute path */
640 static struct uri_test uri_file_absolute = {
641  "file:/boot/script.ipxe",
642  {
643  .scheme = "file",
644  .path = "/boot/script.ipxe",
645  .epath = "/boot/script.ipxe",
646  },
647 };
648 
649 /** File URI with volume name */
650 static struct uri_test uri_file_volume = {
651  "file://hpilo/boot/script.ipxe",
652  {
653  .scheme = "file",
654  .host = "hpilo",
655  .path = "/boot/script.ipxe",
656  .epath = "/boot/script.ipxe",
657  },
658 };
659 
660 /** Relative URI with colons in path */
661 static struct uri_test uri_colons = {
662  "/boot/52:54:00:12:34:56/boot.ipxe",
663  {
664  .path = "/boot/52:54:00:12:34:56/boot.ipxe",
665  .epath = "/boot/52:54:00:12:34:56/boot.ipxe",
666  },
667 };
668 
669 /** URI with port number */
671  "http://192.168.0.1:8080/boot.php",
672  80,
673  8080,
674 };
675 
676 /** URI without port number */
678  "http://192.168.0.1/boot.php",
679  80,
680  80,
681 };
682 
683 /** Simple path resolution test */
685  "/etc/passwd",
686  "group",
687  "/etc/group",
688 };
689 
690 /** Path resolution test with "." and ".." elements */
692  "/var/lib/tftpboot/pxe/pxelinux.0",
693  "./../ipxe/undionly.kpxe",
694  "/var/lib/tftpboot/ipxe/undionly.kpxe",
695 };
696 
697 /** Path resolution test terminating with directory */
699  "/test/cgi-bin.pl/boot.ipxe",
700  "..",
701  "/test/",
702 };
703 
704 /** Path resolution test with excessive ".." elements */
706  "/var/lib/tftpboot/ipxe.pxe",
707  "../../../../../../../foo",
708  "/foo",
709 };
710 
711 /** Path resolution test with absolute path */
713  "/var/lib/tftpboot",
714  "/etc/hostname",
715  "/etc/hostname",
716 };
717 
718 /** Relative URI resolution test */
720  "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
721  "initrd.img",
722  "http://boot.ipxe.org/demo/initrd.img",
723 };
724 
725 /** Absolute URI resolution test */
727  "http://boot.ipxe.org/demo/boot.php",
728  "ftp://192.168.0.1/boot.ipxe",
729  "ftp://192.168.0.1/boot.ipxe",
730 };
731 
732 /** Absolute path URI resolution test */
734  "http://boot.ipxe.org/demo/boot.php#test",
735  "/demo/vmlinuz",
736  "http://boot.ipxe.org/demo/vmlinuz",
737 };
738 
739 /** Query URI resolution test */
740 static struct uri_resolve_test uri_query = {
741  "http://10.253.253.1/test.pl?mac=02-00-69-50-58-45",
742  "?mac=00-1f-16-bc-fe-2f",
743  "http://10.253.253.1/test.pl?mac=00-1f-16-bc-fe-2f",
744 };
745 
746 /** Fragment URI resolution test */
748  "http://192.168.0.254/test#foo",
749  "#bar",
750  "http://192.168.0.254/test#bar",
751 };
752 
753 /** PXE URI with absolute URI */
755  {
756  /* 192.168.0.3 */
757  .sin = {
758  .sin_family = AF_INET,
759  .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
760  },
761  },
762  "http://not.a.tftp/uri",
763  {
764  .scheme = "http",
765  .host = "not.a.tftp",
766  .path = "/uri",
767  .epath = "/uri",
768  },
769  "http://not.a.tftp/uri",
770 };
771 
772 /** PXE URI with absolute path */
774  {
775  /* 192.168.0.2 */
776  .sin = {
777  .sin_family = AF_INET,
778  .sin_addr = { .s_addr = htonl ( 0xc0a80002 ) },
779  },
780  },
781  "/absolute/path",
782  {
783  .scheme = "tftp",
784  .host = "192.168.0.2",
785  .path = "//absolute/path",
786  .epath = "//absolute/path",
787  },
788  "tftp://192.168.0.2//absolute/path",
789 };
790 
791 /** PXE URI with relative path */
793  {
794  /* 192.168.0.3 */
795  .sin = {
796  .sin_family = AF_INET,
797  .sin_addr = { .s_addr = htonl ( 0xc0a80003 ) },
798  },
799  },
800  "relative/path",
801  {
802  .scheme = "tftp",
803  .host = "192.168.0.3",
804  .path = "/relative/path",
805  .epath = "/relative/path",
806  },
807  "tftp://192.168.0.3/relative/path",
808 };
809 
810 /** PXE URI with path containing special characters */
811 static struct uri_pxe_test uri_pxe_icky = {
812  {
813  /* 10.0.0.6 */
814  .sin = {
815  .sin_family = AF_INET,
816  .sin_addr = { .s_addr = htonl ( 0x0a000006 ) },
817  },
818  },
819  "C:\\tftpboot\\icky#path",
820  {
821  .scheme = "tftp",
822  .host = "10.0.0.6",
823  .path = "/C:\\tftpboot\\icky#path",
824  .epath = "/C:\\tftpboot\\icky#path",
825  },
826  "tftp://10.0.0.6/C:\\tftpboot\\icky#path",
827 };
828 
829 /** PXE URI with custom port */
830 static struct uri_pxe_test uri_pxe_port = {
831  {
832  /* 192.168.0.1:4069 */
833  .sin = {
834  .sin_family = AF_INET,
835  .sin_addr = { .s_addr = htonl ( 0xc0a80001 ) },
836  .sin_port = htons ( 4069 ),
837  },
838  },
839  "/another/path",
840  {
841  .scheme = "tftp",
842  .host = "192.168.0.1",
843  .port = "4069",
844  .path = "//another/path",
845  .epath = "//another/path",
846  },
847  "tftp://192.168.0.1:4069//another/path",
848 };
849 
850 /** Current working URI test */
851 static struct uri_churi_test uri_churi[] = {
852  {
853  "http://boot.ipxe.org/demo/boot.php",
854  "http://boot.ipxe.org/demo/boot.php",
855  },
856  {
857  "?vendor=10ec&device=8139",
858  "http://boot.ipxe.org/demo/boot.php?vendor=10ec&device=8139",
859  },
860  {
861  "fedora/fedora.ipxe",
862  "http://boot.ipxe.org/demo/fedora/fedora.ipxe",
863  },
864  {
865  "vmlinuz",
866  "http://boot.ipxe.org/demo/fedora/vmlinuz",
867  },
868  {
869  "http://local/boot/initrd.img",
870  "http://local/boot/initrd.img",
871  },
872  {
873  "modules/8139too.ko",
874  "http://local/boot/modules/8139too.ko",
875  },
876  {
877  NULL,
878  NULL,
879  }
880 };
881 
882 /** Form parameter URI test list */
884  {
885  "vendor",
886  "10ec",
887  },
888  {
889  "device",
890  "8139",
891  },
892  {
893  "uuid",
894  "f59fac00-758f-498f-9fe5-87d790045d94",
895  },
896  {
897  NULL,
898  NULL,
899  }
900 };
901 
902 /** Form parameter URI test */
903 static struct uri_params_test uri_params = {
904  "http://boot.ipxe.org/demo/boot.php##params",
905  {
906  .scheme = "http",
907  .host = "boot.ipxe.org",
908  .path = "/demo/boot.php",
909  .epath = "/demo/boot.php",
910  },
911  NULL,
913 };
914 
915 /** Named form parameter URI test list */
917  {
918  "mac",
919  "00:1e:65:80:d3:b6",
920  },
921  {
922  "serial",
923  "LXTQ20Z1139322762F2000",
924  },
925  {
926  NULL,
927  NULL,
928  }
929 };
930 
931 /** Named form parameter URI test */
933  "http://192.168.100.4:3001/register##params=foo",
934  {
935  .scheme = "http",
936  .host = "192.168.100.4",
937  .port = "3001",
938  .path = "/register",
939  .epath = "/register",
940  },
941  "foo",
943 };
944 
945 /**
946  * Perform URI self-test
947  *
948  */
949 static void uri_test_exec ( void ) {
950 
951  /* URI parsing, formatting, and duplication tests */
960  uri_parse_ok ( &uri_http_escaped_improper ); /* Parse only */
964  uri_parse_ok ( &uri_ipv6_local_non_conforming ); /* Parse only */
970 
971  /** URI port number tests */
974 
975  /** Path resolution tests */
981 
982  /** URI resolution tests */
988 
989  /* PXE URI construction tests */
995 
996  /* Current working URI tests */
998 
999  /* Form parameter URI tests */
1002 }
1003 
1004 /** URI self-test */
1006  .name = "uri",
1007  .exec = uri_test_exec,
1008 };
const char * equery
Query (with original URI encoding)
Definition: uri.h:84
TCP/IP socket address.
Definition: tcpip.h:75
static struct uri_test uri_ipv6_local
IPv6 URI with link-local address.
Definition: uri_test.c:595
A URI parsing/formatting test.
Definition: uri_test.c:43
unsigned int default_port
Default port number.
Definition: uri_test.c:55
static void uri_put(struct uri *uri)
Decrement URI reference count.
Definition: uri.h:205
const char * value
Value.
Definition: uri_test.c:100
static struct uri_test uri_ipv6
IPv6 URI.
Definition: uri_test.c:572
static struct uri * uri_get(struct uri *uri)
Increment URI reference count.
Definition: uri.h:194
static struct uri_resolve_test uri_absolute
Absolute URI resolution test.
Definition: uri_test.c:726
static void uri_churi_okx(struct uri_churi_test *test, const char *file, unsigned int line)
Report current working URI test result.
Definition: uri_test.c:364
const char * string
URI string.
Definition: uri_test.c:106
const char * string
URI string (for display only; cannot be reparsed)
Definition: uri_test.c:84
const char * filename
Filename.
Definition: uri_test.c:80
#define for_each_param(param, params)
Iterate over all form parameters in a list.
Definition: params.h:75
static struct uri_port_test uri_explicit_port
URI with port number.
Definition: uri_test.c:670
static void uri_resolve_okx(struct uri_resolve_test *test, const char *file, unsigned int line)
Report URI resolution test result.
Definition: uri_test.c:273
const char * string
URI string.
Definition: uri_test.c:45
static struct uri_pxe_test uri_pxe_relative_path
PXE URI with relative path.
Definition: uri_test.c:792
struct uri * pxe_uri(struct sockaddr *sa_server, const char *filename)
Construct URI from server address and filename.
Definition: uri.c:808
static struct uri_test uri_http_escaped
HTTP URI with escaped characters.
Definition: uri_test.c:541
static void uri_okx(struct uri *uri, struct uri *expected, const char *file, unsigned int line)
Report URI equality test result.
Definition: uri_test.c:142
static __always_inline int off_t userptr_t second
Definition: efi_uaccess.h:80
static struct uri_test uri_empty
Empty URI.
Definition: uri_test.c:488
struct sockaddr_in6 sin6
Definition: uri_test.c:76
A form parameter list.
Definition: params.h:16
struct sockaddr sa
Definition: uri_test.c:74
#define uri_parse_format_dup_ok(test)
Definition: uri_test.c:240
static struct uri_pxe_test uri_pxe_absolute
PXE URI with absolute URI.
Definition: uri_test.c:754
static struct uri_params_test_list uri_params_list[]
Form parameter URI test list.
Definition: uri_test.c:883
static struct uri_params_test uri_params
Form parameter URI test.
Definition: uri_test.c:903
static struct uri_test uri_file_volume
File URI with volume name.
Definition: uri_test.c:650
Self-test infrastructure.
const char * name
Test set name.
Definition: test.h:17
static struct uri_test uri_file_relative
File URI with relative (opaque) path.
Definition: uri_test.c:631
IPv4 socket address.
Definition: in.h:82
static struct uri_pxe_test uri_pxe_port
PXE URI with custom port.
Definition: uri_test.c:830
static struct uri_resolve_test uri_fragment
Fragment URI resolution test.
Definition: uri_test.c:747
Uniform Resource Identifiers.
static void uri_test_exec(void)
Perform URI self-test.
Definition: uri_test.c:949
sa_family_t sin_family
Socket address family (part of struct sockaddr)
Definition: in.h:87
A self-test set.
Definition: test.h:15
#define htonl(value)
Definition: byteswap.h:133
A PXE URI test.
Definition: uri_test.c:71
#define uri_port_ok(test)
Definition: uri_test.c:264
static struct uri_resolve_test uri_query
Query URI resolution test.
Definition: uri_test.c:740
#define uri_resolve_ok(test)
Definition: uri_test.c:305
const char * port
Port number.
Definition: uri.h:78
static struct uri_resolve_test uri_relative_path
Path resolution test with "." and ".." elements.
Definition: uri_test.c:691
struct sockaddr_tcpip st
Definition: uri_test.c:77
const char * key
Key.
Definition: uri_test.c:98
static void uri_format_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI formatting test result.
Definition: uri_test.c:187
static struct uri_resolve_test uri_absolute_path
Path resolution test with absolute path.
Definition: uri_test.c:712
const char * scheme
Scheme.
Definition: uri.h:68
union uri_pxe_test::@424 server
Server address.
u8 port
Port number.
Definition: CIB_PRM.h:31
static struct uri_test uri_boot_ipxe_org
Basic HTTP URI.
Definition: uri_test.c:493
#define okx(success, file, line)
Report test result.
Definition: test.h:44
void churi(struct uri *uri)
Change working URI.
Definition: cwuri.c:45
static struct uri_resolve_test uri_directory_path
Path resolution test terminating with directory.
Definition: uri_test.c:698
struct parameter * add_parameter(struct parameters *params, const char *key, const char *value)
Add form parameter.
Definition: params.c:128
Form parameters.
static struct uri_test uri_iscsi
iSCSI URI
Definition: uri_test.c:622
const char * relative
Relative path or URI.
Definition: uri_test.c:65
const char * base
Base path or URI.
Definition: uri_test.c:63
A URI port number test.
Definition: uri_test.c:51
static struct uri_test uri_http_escaped_improper
HTTP URI with improperly escaped characters.
Definition: uri_test.c:554
const char * path
Path (after URI decoding)
Definition: uri.h:80
static void uri_params_list_okx(struct uri_params_test *test, struct uri *uri, const char *file, unsigned int line)
Report form parameter URI test list result.
Definition: uri_test.c:413
static struct uri_resolve_test uri_excessive_path
Path resolution test with excessive ".." elements.
Definition: uri_test.c:705
Transport-network layer interface.
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:471
struct parameters * create_parameters(const char *name)
Create form parameter list.
Definition: params.c:86
static struct uri_churi_test uri_churi[]
Current working URI test.
Definition: uri_test.c:851
char * format_uri_alloc(const struct uri *uri)
Format URI.
Definition: uri.c:540
static struct uri_test uri_http_all
HTTP URI with all the trimmings.
Definition: uri_test.c:525
struct self_test uri_test __self_test
URI self-test.
Definition: uri_test.c:1005
char * resolve_path(const char *base_path, const char *relative_path)
Resolve base+relative path.
Definition: uri.c:632
struct parameters * params
Form parameters.
Definition: uri.h:88
static struct uri_test uri_colons
Relative URI with colons in path.
Definition: uri_test.c:661
Generalized socket address structure.
Definition: socket.h:96
A form parameter URI test.
Definition: uri_test.c:104
static struct uri_test uri_ipv6_port
IPv6 URI with port.
Definition: uri_test.c:583
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
static struct uri_resolve_test uri_absolute_uri_path
Absolute path URI resolution test.
Definition: uri_test.c:733
struct hv_monitor_parameter param[4][32]
Parameters.
Definition: hyperv.h:24
struct uri * uri_dup(const struct uri *uri)
Duplicate URI.
Definition: uri.c:594
uint8_t * tmp
Definition: entropy.h:156
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
static void uri_port_okx(struct uri_port_test *test, const char *file, unsigned int line)
Report URI port number test result.
Definition: uri_test.c:250
struct list_head list
List of form parameters.
Definition: params.h:30
A current working URI test.
Definition: uri_test.c:88
static struct uri_params_test uri_named_params
Named form parameter URI test.
Definition: uri_test.c:932
const char * host
Host name.
Definition: uri.h:76
A URI or path resolution test.
Definition: uri_test.c:61
uint16_t base
Base address.
Definition: edd.h:14
#define uri_params_ok(test)
Definition: uri_test.c:485
const char * expected
Expected new working URI.
Definition: uri_test.c:92
static struct uri_test uri_path
Basic path-only URI.
Definition: uri_test.c:512
static struct uri_test uri_host
Basic host-only URI.
Definition: uri_test.c:506
static void uri_dup_okx(struct uri *uri, const char *file, unsigned int line)
Report URI duplication test result.
Definition: uri_test.c:214
uint8_t formatted[5]
Formatted area.
Definition: smbios.h:29
static void uri_pxe_okx(struct uri_pxe_test *test, const char *file, unsigned int line)
Report URI PXE test result.
Definition: uri_test.c:338
const char * efragment
Fragment (with original URI encoding)
Definition: uri.h:86
static struct uri_test uri_mailto
Basic opaque URI.
Definition: uri_test.c:500
static struct uri_resolve_test uri_relative
Relative URI resolution test.
Definition: uri_test.c:719
uint32_t len
Length.
Definition: ena.h:14
const char * opaque
Opaque part.
Definition: uri.h:70
const char * string
URI string.
Definition: uri_test.c:53
#define uri_churi_ok(test)
Definition: uri_test.c:403
int strcmp(const char *first, const char *second)
Compare strings.
Definition: string.c:173
static void uri_resolve_path_okx(struct uri_resolve_test *test, const char *file, unsigned int line)
Report path resolution test result.
Definition: uri_test.c:314
static struct uri_pxe_test uri_pxe_absolute_path
PXE URI with absolute path.
Definition: uri_test.c:773
static struct uri_test uri_file_absolute
File URI with absolute path.
Definition: uri_test.c:640
unsigned int uri_port(const struct uri *uri, unsigned int default_port)
Get port from URI.
Definition: uri.c:455
const char * password
Password.
Definition: uri.h:74
const char * epath
Path (with original URI encoding)
Definition: uri.h:82
#define uri_pxe_ok(test)
Definition: uri_test.c:355
static struct uri_test uri_path_escaped
Path-only URI with escaped characters.
Definition: uri_test.c:519
IPv6 socket address.
Definition: in.h:115
const char * user
User name.
Definition: uri.h:72
static void uri_params_okx(struct uri_params_test *test, const char *file, unsigned int line)
Report form parameter URI test result.
Definition: uri_test.c:446
const char * name
Parameter list name.
Definition: uri_test.c:110
A Uniform Resource Identifier.
Definition: uri.h:64
A form parameter.
Definition: params.h:28
A form parameter URI test list.
Definition: uri_test.c:96
struct uri * resolve_uri(const struct uri *base_uri, struct uri *relative_uri)
Resolve base+relative URI.
Definition: uri.c:694
static struct uri_resolve_test uri_simple_path
Simple path resolution test.
Definition: uri_test.c:684
unsigned int port
Expected port number.
Definition: uri_test.c:57
struct sockaddr_in sin
Definition: uri_test.c:75
static struct uri_params_test_list uri_named_params_list[]
Named form parameter URI test list.
Definition: uri_test.c:916
#define uri_resolve_path_ok(test)
Definition: uri_test.c:328
const char * resolved
Expected resolved path or URI.
Definition: uri_test.c:67
struct uri * cwuri
Current working URI.
Definition: cwuri.c:38
static int uristrcmp(const char *first, const char *second)
Compare two URI component strings.
Definition: uri_test.c:122
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static void uri_parse_format_dup_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI combined parsing and formatting test result.
Definition: uri_test.c:233
static struct uri_port_test uri_default_port
URI without port number.
Definition: uri_test.c:677
#define uri_parse_ok(test)
Definition: uri_test.c:178
String functions.
static struct uri_pxe_test uri_pxe_icky
PXE URI with path containing special characters.
Definition: uri_test.c:811
#define htons(value)
Definition: byteswap.h:135
static struct uri_test uri_ipv6_local_non_conforming
IPv6 URI with link-local address not conforming to RFC 6874.
Definition: uri_test.c:606
uint32_t first
Length to skip in first segment.
Definition: pccrc.h:23
const char * relative
Relative URI.
Definition: uri_test.c:90
#define AF_INET
IPv4 Internet addresses.
Definition: socket.h:63
static int test
Definition: epic100.c:73
struct uri * parse_uri(const char *uri_string)
Parse URI.
Definition: uri.c:296
static void uri_parse_okx(struct uri_test *test, const char *file, unsigned int line)
Report URI parsing test result.
Definition: uri_test.c:167
struct uri_params_test_list * list
Parameter list.
Definition: uri_test.c:112