Blame


1 92e07b23 2022-12-25 op /*
2 92e07b23 2022-12-25 op * Copyright (c) 2022 Omar Polo <op@omarpolo.com>
3 92e07b23 2022-12-25 op *
4 92e07b23 2022-12-25 op * Permission to use, copy, modify, and distribute this software for any
5 92e07b23 2022-12-25 op * purpose with or without fee is hereby granted, provided that the above
6 92e07b23 2022-12-25 op * copyright notice and this permission notice appear in all copies.
7 92e07b23 2022-12-25 op *
8 92e07b23 2022-12-25 op * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 92e07b23 2022-12-25 op * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 92e07b23 2022-12-25 op * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 92e07b23 2022-12-25 op * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 92e07b23 2022-12-25 op * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 92e07b23 2022-12-25 op * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 92e07b23 2022-12-25 op * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 92e07b23 2022-12-25 op */
16 92e07b23 2022-12-25 op
17 92e07b23 2022-12-25 op #include <err.h>
18 92e07b23 2022-12-25 op #include <errno.h>
19 92e07b23 2022-12-25 op #include <stdio.h>
20 92e07b23 2022-12-25 op #include <string.h>
21 92e07b23 2022-12-25 op
22 92e07b23 2022-12-25 op #include "iri.h"
23 92e07b23 2022-12-25 op
24 92e07b23 2022-12-25 op static int
25 5cc70f14 2022-12-26 op resolve(const char *base, const char *ref, const char *expected)
26 92e07b23 2022-12-25 op {
27 92e07b23 2022-12-25 op static struct iri i;
28 92e07b23 2022-12-25 op char buf[512];
29 92e07b23 2022-12-25 op
30 92e07b23 2022-12-25 op if (iri_parse(base, ref, &i) == -1) {
31 92e07b23 2022-12-25 op fprintf(stderr, "FAIL (\"%s\", \"%s\") %s\n", base, ref,
32 92e07b23 2022-12-25 op strerror(errno));
33 92e07b23 2022-12-25 op return (1);
34 92e07b23 2022-12-25 op }
35 92e07b23 2022-12-25 op
36 92e07b23 2022-12-25 op if (iri_unparse(&i, buf, sizeof(buf)) == -1) {
37 92e07b23 2022-12-25 op fprintf(stderr, "FAIL (\"%s\", \"%s\") %s\n", base, ref,
38 92e07b23 2022-12-25 op strerror(errno));
39 92e07b23 2022-12-25 op return (1);
40 92e07b23 2022-12-25 op }
41 92e07b23 2022-12-25 op
42 92e07b23 2022-12-25 op if (strcmp(buf, expected) != 0) {
43 92e07b23 2022-12-25 op fprintf(stderr, "FAIL (\"%s\", \"%s\")\n", base, ref);
44 92e07b23 2022-12-25 op fprintf(stderr, "got:\t%s\n", buf);
45 92e07b23 2022-12-25 op fprintf(stderr, "want:\t%s\n", expected);
46 92e07b23 2022-12-25 op return (1);
47 92e07b23 2022-12-25 op }
48 92e07b23 2022-12-25 op
49 92e07b23 2022-12-25 op fprintf(stderr, "OK (\"%s\", \"%s\") -> %s\n", base, ref, expected);
50 92e07b23 2022-12-25 op return (0);
51 92e07b23 2022-12-25 op }
52 92e07b23 2022-12-25 op
53 92e07b23 2022-12-25 op int
54 92e07b23 2022-12-25 op main(void)
55 92e07b23 2022-12-25 op {
56 92e07b23 2022-12-25 op const char *base = "http://a/b/c/d;p?q";
57 92e07b23 2022-12-25 op int ret = 0;
58 92e07b23 2022-12-25 op
59 5cc70f14 2022-12-26 op ret |= resolve(base, "g:h", "g:h");
60 5cc70f14 2022-12-26 op ret |= resolve(base, "g", "http://a/b/c/g");
61 5cc70f14 2022-12-26 op ret |= resolve(base, "./g", "http://a/b/c/g");
62 5cc70f14 2022-12-26 op ret |= resolve(base, "g/", "http://a/b/c/g/");
63 5cc70f14 2022-12-26 op ret |= resolve(base, "/g", "http://a/g");
64 92e07b23 2022-12-25 op
65 92e07b23 2022-12-25 op /*
66 92e07b23 2022-12-25 op * the RFC says "http://g" but we always normalize an
67 92e07b23 2022-12-25 op * empty path to "/" if there is an authority.
68 92e07b23 2022-12-25 op */
69 5cc70f14 2022-12-26 op ret |= resolve(base, "//g", "http://g/");
70 92e07b23 2022-12-25 op
71 5cc70f14 2022-12-26 op ret |= resolve(base, "?y", "http://a/b/c/d;p?y");
72 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y", "http://a/b/c/g?y");
73 5cc70f14 2022-12-26 op ret |= resolve(base, "#s", "http://a/b/c/d;p?q#s");
74 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s", "http://a/b/c/g#s");
75 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y#s", "http://a/b/c/g?y#s");
76 5cc70f14 2022-12-26 op ret |= resolve(base, ";x", "http://a/b/c/;x");
77 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x", "http://a/b/c/g;x");
78 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x?y#s", "http://a/b/c/g;x?y#s");
79 5cc70f14 2022-12-26 op ret |= resolve(base, "", "http://a/b/c/d;p?q");
80 5cc70f14 2022-12-26 op ret |= resolve(base, ".", "http://a/b/c/");
81 5cc70f14 2022-12-26 op ret |= resolve(base, "./", "http://a/b/c/");
82 5cc70f14 2022-12-26 op ret |= resolve(base, "..", "http://a/b/");
83 5cc70f14 2022-12-26 op ret |= resolve(base, "../", "http://a/b/");
84 5cc70f14 2022-12-26 op ret |= resolve(base, "../g", "http://a/b/g");
85 5cc70f14 2022-12-26 op ret |= resolve(base, "../..", "http://a/");
86 5cc70f14 2022-12-26 op ret |= resolve(base, "../../", "http://a/");
87 5cc70f14 2022-12-26 op ret |= resolve(base, "../../g", "http://a/g");
88 92e07b23 2022-12-25 op
89 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../g", "http://a/g");
90 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../../g", "http://a/g");
91 5cc70f14 2022-12-26 op ret |= resolve(base, "/./g", "http://a/g");
92 5cc70f14 2022-12-26 op ret |= resolve(base, "/../g", "http://a/g");
93 5cc70f14 2022-12-26 op ret |= resolve(base, "g.", "http://a/b/c/g.");
94 5cc70f14 2022-12-26 op ret |= resolve(base, ".g", "http://a/b/c/.g");
95 5cc70f14 2022-12-26 op ret |= resolve(base, "g..", "http://a/b/c/g..");
96 5cc70f14 2022-12-26 op ret |= resolve(base, "..g", "http://a/b/c/..g");
97 92e07b23 2022-12-25 op
98 5cc70f14 2022-12-26 op ret |= resolve(base, "./../g", "http://a/b/g");
99 5cc70f14 2022-12-26 op ret |= resolve(base, "./g/.", "http://a/b/c/g/");
100 5cc70f14 2022-12-26 op ret |= resolve(base, "g/./h", "http://a/b/c/g/h");
101 5cc70f14 2022-12-26 op ret |= resolve(base, "g/../h", "http://a/b/c/h");
102 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/./y", "http://a/b/c/g;x=1/y");
103 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/../y", "http://a/b/c/y");
104 92e07b23 2022-12-25 op
105 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/./x", "http://a/b/c/g?y/./x");
106 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/../x", "http://a/b/c/g?y/../x");
107 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/./x", "http://a/b/c/g#s/./x");
108 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/../x", "http://a/b/c/g#s/../x");
109 92e07b23 2022-12-25 op
110 5cc70f14 2022-12-26 op ret |= resolve(base, "http:g", "http:g");
111 92e07b23 2022-12-25 op
112 92e07b23 2022-12-25 op return (ret);
113 92e07b23 2022-12-25 op }