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 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%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 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%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 3f2ab305 2022-12-26 op fprintf(stderr, "FAIL resolve(\"%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 3f2ab305 2022-12-26 op fprintf(stderr, "OK resolve(\"%s\", \"%s\") -> %s\n", base, ref,
50 3f2ab305 2022-12-26 op expected);
51 92e07b23 2022-12-25 op return (0);
52 92e07b23 2022-12-25 op }
53 92e07b23 2022-12-25 op
54 9987c6fb 2022-12-26 op static int
55 9987c6fb 2022-12-26 op setquery(const char *iri, const char *query, const char *expected)
56 9987c6fb 2022-12-26 op {
57 9987c6fb 2022-12-26 op static struct iri i;
58 9987c6fb 2022-12-26 op char buf[512];
59 9987c6fb 2022-12-26 op
60 9987c6fb 2022-12-26 op if (iri_parse(NULL, iri, &i) == -1) {
61 9987c6fb 2022-12-26 op fprintf(stderr, "FAIL can't parse <%s>: %s\n", iri,
62 9987c6fb 2022-12-26 op strerror(errno));
63 9987c6fb 2022-12-26 op return (1);
64 9987c6fb 2022-12-26 op }
65 9987c6fb 2022-12-26 op
66 9987c6fb 2022-12-26 op if (iri_setquery(&i, query) == -1) {
67 9987c6fb 2022-12-26 op fprintf(stderr, "FAIL setting query \"%s\": %s\n", query,
68 9987c6fb 2022-12-26 op strerror(errno));
69 9987c6fb 2022-12-26 op return (1);
70 9987c6fb 2022-12-26 op }
71 9987c6fb 2022-12-26 op
72 9987c6fb 2022-12-26 op if (iri_unparse(&i, buf, sizeof(buf)) == -1) {
73 9987c6fb 2022-12-26 op fprintf(stderr, "FAIL unparsing <%s> with query %s\n",
74 9987c6fb 2022-12-26 op iri, query);
75 9987c6fb 2022-12-26 op return (1);
76 9987c6fb 2022-12-26 op }
77 9987c6fb 2022-12-26 op
78 9987c6fb 2022-12-26 op if (strcmp(buf, expected) != 0) {
79 9987c6fb 2022-12-26 op fprintf(stderr, "FAIL setquery(\"%s\", \"%s\")\n", iri, query);
80 9987c6fb 2022-12-26 op fprintf(stderr, "got:\t%s\n", buf);
81 9987c6fb 2022-12-26 op fprintf(stderr, "want:\t%s\n", expected);
82 9987c6fb 2022-12-26 op return (1);
83 9987c6fb 2022-12-26 op }
84 9987c6fb 2022-12-26 op
85 9987c6fb 2022-12-26 op fprintf(stderr, "OK setquery(\"%s\", \"%s\") -> %s\n", iri, query,
86 9987c6fb 2022-12-26 op expected);
87 9987c6fb 2022-12-26 op return (0);
88 9987c6fb 2022-12-26 op }
89 9987c6fb 2022-12-26 op
90 92e07b23 2022-12-25 op int
91 92e07b23 2022-12-25 op main(void)
92 92e07b23 2022-12-25 op {
93 9987c6fb 2022-12-26 op const char *base;
94 92e07b23 2022-12-25 op int ret = 0;
95 92e07b23 2022-12-25 op
96 9987c6fb 2022-12-26 op /* RFC 3986 tests */
97 9987c6fb 2022-12-26 op
98 9987c6fb 2022-12-26 op base = "http://a/b/c/d;p?q";
99 9987c6fb 2022-12-26 op
100 5cc70f14 2022-12-26 op ret |= resolve(base, "g:h", "g:h");
101 5cc70f14 2022-12-26 op ret |= resolve(base, "g", "http://a/b/c/g");
102 5cc70f14 2022-12-26 op ret |= resolve(base, "./g", "http://a/b/c/g");
103 5cc70f14 2022-12-26 op ret |= resolve(base, "g/", "http://a/b/c/g/");
104 5cc70f14 2022-12-26 op ret |= resolve(base, "/g", "http://a/g");
105 92e07b23 2022-12-25 op
106 92e07b23 2022-12-25 op /*
107 92e07b23 2022-12-25 op * the RFC says "http://g" but we always normalize an
108 92e07b23 2022-12-25 op * empty path to "/" if there is an authority.
109 92e07b23 2022-12-25 op */
110 5cc70f14 2022-12-26 op ret |= resolve(base, "//g", "http://g/");
111 92e07b23 2022-12-25 op
112 5cc70f14 2022-12-26 op ret |= resolve(base, "?y", "http://a/b/c/d;p?y");
113 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y", "http://a/b/c/g?y");
114 5cc70f14 2022-12-26 op ret |= resolve(base, "#s", "http://a/b/c/d;p?q#s");
115 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s", "http://a/b/c/g#s");
116 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y#s", "http://a/b/c/g?y#s");
117 5cc70f14 2022-12-26 op ret |= resolve(base, ";x", "http://a/b/c/;x");
118 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x", "http://a/b/c/g;x");
119 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x?y#s", "http://a/b/c/g;x?y#s");
120 5cc70f14 2022-12-26 op ret |= resolve(base, "", "http://a/b/c/d;p?q");
121 5cc70f14 2022-12-26 op ret |= resolve(base, ".", "http://a/b/c/");
122 5cc70f14 2022-12-26 op ret |= resolve(base, "./", "http://a/b/c/");
123 5cc70f14 2022-12-26 op ret |= resolve(base, "..", "http://a/b/");
124 5cc70f14 2022-12-26 op ret |= resolve(base, "../", "http://a/b/");
125 5cc70f14 2022-12-26 op ret |= resolve(base, "../g", "http://a/b/g");
126 5cc70f14 2022-12-26 op ret |= resolve(base, "../..", "http://a/");
127 5cc70f14 2022-12-26 op ret |= resolve(base, "../../", "http://a/");
128 5cc70f14 2022-12-26 op ret |= resolve(base, "../../g", "http://a/g");
129 92e07b23 2022-12-25 op
130 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../g", "http://a/g");
131 5cc70f14 2022-12-26 op ret |= resolve(base, "../../../../g", "http://a/g");
132 5cc70f14 2022-12-26 op ret |= resolve(base, "/./g", "http://a/g");
133 5cc70f14 2022-12-26 op ret |= resolve(base, "/../g", "http://a/g");
134 5cc70f14 2022-12-26 op ret |= resolve(base, "g.", "http://a/b/c/g.");
135 5cc70f14 2022-12-26 op ret |= resolve(base, ".g", "http://a/b/c/.g");
136 5cc70f14 2022-12-26 op ret |= resolve(base, "g..", "http://a/b/c/g..");
137 5cc70f14 2022-12-26 op ret |= resolve(base, "..g", "http://a/b/c/..g");
138 92e07b23 2022-12-25 op
139 5cc70f14 2022-12-26 op ret |= resolve(base, "./../g", "http://a/b/g");
140 5cc70f14 2022-12-26 op ret |= resolve(base, "./g/.", "http://a/b/c/g/");
141 5cc70f14 2022-12-26 op ret |= resolve(base, "g/./h", "http://a/b/c/g/h");
142 5cc70f14 2022-12-26 op ret |= resolve(base, "g/../h", "http://a/b/c/h");
143 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/./y", "http://a/b/c/g;x=1/y");
144 5cc70f14 2022-12-26 op ret |= resolve(base, "g;x=1/../y", "http://a/b/c/y");
145 92e07b23 2022-12-25 op
146 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/./x", "http://a/b/c/g?y/./x");
147 5cc70f14 2022-12-26 op ret |= resolve(base, "g?y/../x", "http://a/b/c/g?y/../x");
148 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/./x", "http://a/b/c/g#s/./x");
149 5cc70f14 2022-12-26 op ret |= resolve(base, "g#s/../x", "http://a/b/c/g#s/../x");
150 92e07b23 2022-12-25 op
151 5cc70f14 2022-12-26 op ret |= resolve(base, "http:g", "http:g");
152 92e07b23 2022-12-25 op
153 9987c6fb 2022-12-26 op /* extra tests */
154 9987c6fb 2022-12-26 op
155 9987c6fb 2022-12-26 op base = "gemini://a/b/c";
156 9987c6fb 2022-12-26 op
157 9987c6fb 2022-12-26 op ret |= setquery(base, "hw", "gemini://a/b/c?hw");
158 9987c6fb 2022-12-26 op ret |= setquery(base, "h w", "gemini://a/b/c?h%20w");
159 9987c6fb 2022-12-26 op ret |= setquery(base, "100%", "gemini://a/b/c?100%25");
160 9987c6fb 2022-12-26 op ret |= setquery(base, "%20", "gemini://a/b/c?%2520");
161 9987c6fb 2022-12-26 op
162 92e07b23 2022-12-25 op return (ret);
163 92e07b23 2022-12-25 op }