Git fork
1#include "unit-test.h"
2#include "urlmatch.h"
3
4static void check_url_normalizable(const char *url, unsigned int normalizable)
5{
6 char *url_norm = url_normalize(url, NULL);
7
8 cl_assert_equal_i(normalizable, url_norm ? 1 : 0);
9 free(url_norm);
10}
11
12static void check_normalized_url(const char *url, const char *expect)
13{
14 char *url_norm = url_normalize(url, NULL);
15
16 cl_assert_equal_s(url_norm, expect);
17 free(url_norm);
18}
19
20static void compare_normalized_urls(const char *url1, const char *url2,
21 unsigned int equal)
22{
23 char *url1_norm = url_normalize(url1, NULL);
24 char *url2_norm = url_normalize(url2, NULL);
25
26 if (equal) {
27 cl_assert_equal_s(url1_norm, url2_norm);
28 } else {
29 cl_assert(strcmp(url1_norm, url2_norm) != 0);
30 }
31 free(url1_norm);
32 free(url2_norm);
33}
34
35static void check_normalized_url_length(const char *url, size_t len)
36{
37 struct url_info info;
38 char *url_norm = url_normalize(url, &info);
39
40 cl_assert_equal_i(info.url_len, len);
41 free(url_norm);
42}
43
44/* Note that only "file:" URLs should be allowed without a host */
45void test_urlmatch_normalization__scheme(void)
46{
47 check_url_normalizable("", 0);
48 check_url_normalizable("_", 0);
49 check_url_normalizable("scheme", 0);
50 check_url_normalizable("scheme:", 0);
51 check_url_normalizable("scheme:/", 0);
52 check_url_normalizable("scheme://", 0);
53 check_url_normalizable("file", 0);
54 check_url_normalizable("file:", 0);
55 check_url_normalizable("file:/", 0);
56 check_url_normalizable("file://", 1);
57 check_url_normalizable("://acme.co", 0);
58 check_url_normalizable("x_test://acme.co", 0);
59 check_url_normalizable("-test://acme.co", 0);
60 check_url_normalizable("0test://acme.co", 0);
61 check_url_normalizable("+test://acme.co", 0);
62 check_url_normalizable(".test://acme.co", 0);
63 check_url_normalizable("schem%6e://", 0);
64 check_url_normalizable("x-Test+v1.0://acme.co", 1);
65 check_normalized_url("AbCdeF://x.Y", "abcdef://x.y/");
66}
67
68void test_urlmatch_normalization__authority(void)
69{
70 check_url_normalizable("scheme://user:pass@", 0);
71 check_url_normalizable("scheme://?", 0);
72 check_url_normalizable("scheme://#", 0);
73 check_url_normalizable("scheme:///", 0);
74 check_url_normalizable("scheme://:", 0);
75 check_url_normalizable("scheme://:555", 0);
76 check_url_normalizable("file://user:pass@", 1);
77 check_url_normalizable("file://?", 1);
78 check_url_normalizable("file://#", 1);
79 check_url_normalizable("file:///", 1);
80 check_url_normalizable("file://:", 1);
81 check_url_normalizable("file://:555", 0);
82 check_url_normalizable("scheme://user:pass@host", 1);
83 check_url_normalizable("scheme://@host", 1);
84 check_url_normalizable("scheme://%00@host", 1);
85 check_url_normalizable("scheme://%%@host", 0);
86 check_url_normalizable("scheme://host_", 1);
87 check_url_normalizable("scheme://user:pass@host/", 1);
88 check_url_normalizable("scheme://@host/", 1);
89 check_url_normalizable("scheme://host/", 1);
90 check_url_normalizable("scheme://host?x", 1);
91 check_url_normalizable("scheme://host#x", 1);
92 check_url_normalizable("scheme://host/@", 1);
93 check_url_normalizable("scheme://host?@x", 1);
94 check_url_normalizable("scheme://host#@x", 1);
95 check_url_normalizable("scheme://[::1]", 1);
96 check_url_normalizable("scheme://[::1]/", 1);
97 check_url_normalizable("scheme://hos%41/", 0);
98 check_url_normalizable("scheme://[invalid....:/", 1);
99 check_url_normalizable("scheme://invalid....:]/", 1);
100 check_url_normalizable("scheme://invalid....:[/", 0);
101 check_url_normalizable("scheme://invalid....:[", 0);
102}
103
104void test_urlmatch_normalization__port(void)
105{
106 check_url_normalizable("xyz://q@some.host:", 1);
107 check_url_normalizable("xyz://q@some.host:456/", 1);
108 check_url_normalizable("xyz://q@some.host:0", 0);
109 check_url_normalizable("xyz://q@some.host:0000000", 0);
110 check_url_normalizable("xyz://q@some.host:0000001?", 1);
111 check_url_normalizable("xyz://q@some.host:065535#", 1);
112 check_url_normalizable("xyz://q@some.host:65535", 1);
113 check_url_normalizable("xyz://q@some.host:65536", 0);
114 check_url_normalizable("xyz://q@some.host:99999", 0);
115 check_url_normalizable("xyz://q@some.host:100000", 0);
116 check_url_normalizable("xyz://q@some.host:100001", 0);
117 check_url_normalizable("http://q@some.host:80", 1);
118 check_url_normalizable("https://q@some.host:443", 1);
119 check_url_normalizable("http://q@some.host:80/", 1);
120 check_url_normalizable("https://q@some.host:443?", 1);
121 check_url_normalizable("http://q@:8008", 0);
122 check_url_normalizable("http://:8080", 0);
123 check_url_normalizable("http://:", 0);
124 check_url_normalizable("xyz://q@some.host:456/", 1);
125 check_url_normalizable("xyz://[::1]:456/", 1);
126 check_url_normalizable("xyz://[::1]:/", 1);
127 check_url_normalizable("xyz://[::1]:000/", 0);
128 check_url_normalizable("xyz://[::1]:0%300/", 0);
129 check_url_normalizable("xyz://[::1]:0x80/", 0);
130 check_url_normalizable("xyz://[::1]:4294967297/", 0);
131 check_url_normalizable("xyz://[::1]:030f/", 0);
132}
133
134void test_urlmatch_normalization__port_normalization(void)
135{
136 check_normalized_url("http://x:800", "http://x:800/");
137 check_normalized_url("http://x:0800", "http://x:800/");
138 check_normalized_url("http://x:00000800", "http://x:800/");
139 check_normalized_url("http://x:065535", "http://x:65535/");
140 check_normalized_url("http://x:1", "http://x:1/");
141 check_normalized_url("http://x:80", "http://x/");
142 check_normalized_url("http://x:080", "http://x/");
143 check_normalized_url("http://x:000000080", "http://x/");
144 check_normalized_url("https://x:443", "https://x/");
145 check_normalized_url("https://x:0443", "https://x/");
146 check_normalized_url("https://x:000000443", "https://x/");
147}
148
149void test_urlmatch_normalization__general_escape(void)
150{
151 check_url_normalizable("http://x.y?%fg", 0);
152 check_normalized_url("X://W/%7e%41^%3a", "x://w/~A%5E%3A");
153 check_normalized_url("X://W/:/?#[]@", "x://w/:/?#[]@");
154 check_normalized_url("X://W/$&()*+,;=", "x://w/$&()*+,;=");
155 check_normalized_url("X://W/'", "x://w/'");
156 check_normalized_url("X://W?!", "x://w/?!");
157}
158
159void test_urlmatch_normalization__high_bit(void)
160{
161 check_normalized_url(
162 "x://q/\x01\x02\x03\x04\x05\x06\x07\x08\x0e\x0f\x10\x11\x12",
163 "x://q/%01%02%03%04%05%06%07%08%0E%0F%10%11%12");
164 check_normalized_url(
165 "x://q/\x13\x14\x15\x16\x17\x18\x19\x1b\x1c\x1d\x1e\x1f\x7f",
166 "x://q/%13%14%15%16%17%18%19%1B%1C%1D%1E%1F%7F");
167 check_normalized_url(
168 "x://q/\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f",
169 "x://q/%80%81%82%83%84%85%86%87%88%89%8A%8B%8C%8D%8E%8F");
170 check_normalized_url(
171 "x://q/\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f",
172 "x://q/%90%91%92%93%94%95%96%97%98%99%9A%9B%9C%9D%9E%9F");
173 check_normalized_url(
174 "x://q/\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf",
175 "x://q/%A0%A1%A2%A3%A4%A5%A6%A7%A8%A9%AA%AB%AC%AD%AE%AF");
176 check_normalized_url(
177 "x://q/\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf",
178 "x://q/%B0%B1%B2%B3%B4%B5%B6%B7%B8%B9%BA%BB%BC%BD%BE%BF");
179 check_normalized_url(
180 "x://q/\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf",
181 "x://q/%C0%C1%C2%C3%C4%C5%C6%C7%C8%C9%CA%CB%CC%CD%CE%CF");
182 check_normalized_url(
183 "x://q/\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf",
184 "x://q/%D0%D1%D2%D3%D4%D5%D6%D7%D8%D9%DA%DB%DC%DD%DE%DF");
185 check_normalized_url(
186 "x://q/\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef",
187 "x://q/%E0%E1%E2%E3%E4%E5%E6%E7%E8%E9%EA%EB%EC%ED%EE%EF");
188 check_normalized_url(
189 "x://q/\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
190 "x://q/%F0%F1%F2%F3%F4%F5%F6%F7%F8%F9%FA%FB%FC%FD%FE%FF");
191}
192
193void test_urlmatch_normalization__utf8_escape(void)
194{
195 check_normalized_url(
196 "x://q/\xc2\x80\xdf\xbf\xe0\xa0\x80\xef\xbf\xbd\xf0\x90\x80\x80\xf0\xaf\xbf\xbd",
197 "x://q/%C2%80%DF%BF%E0%A0%80%EF%BF%BD%F0%90%80%80%F0%AF%BF%BD");
198}
199
200void test_urlmatch_normalization__username_pass(void)
201{
202 check_normalized_url("x://%41%62(^):%70+d@foo", "x://Ab(%5E):p+d@foo/");
203}
204
205void test_urlmatch_normalization__length(void)
206{
207 check_normalized_url_length("Http://%4d%65:%4d^%70@The.Host", 25);
208 check_normalized_url_length("http://%41:%42@x.y/%61/", 17);
209 check_normalized_url_length("http://@x.y/^", 15);
210}
211
212void test_urlmatch_normalization__dots(void)
213{
214 check_normalized_url("x://y/.", "x://y/");
215 check_normalized_url("x://y/./", "x://y/");
216 check_normalized_url("x://y/a/.", "x://y/a");
217 check_normalized_url("x://y/a/./", "x://y/a/");
218 check_normalized_url("x://y/.?", "x://y/?");
219 check_normalized_url("x://y/./?", "x://y/?");
220 check_normalized_url("x://y/a/.?", "x://y/a?");
221 check_normalized_url("x://y/a/./?", "x://y/a/?");
222 check_normalized_url("x://y/a/./b/.././../c", "x://y/c");
223 check_normalized_url("x://y/a/./b/../.././c/", "x://y/c/");
224 check_normalized_url("x://y/a/./b/.././../c/././.././.", "x://y/");
225 check_url_normalizable("x://y/a/./b/.././../c/././.././..", 0);
226 check_normalized_url("x://y/a/./?/././..", "x://y/a/?/././..");
227 check_normalized_url("x://y/%2e/", "x://y/");
228 check_normalized_url("x://y/%2E/", "x://y/");
229 check_normalized_url("x://y/a/%2e./", "x://y/");
230 check_normalized_url("x://y/b/.%2E/", "x://y/");
231 check_normalized_url("x://y/c/%2e%2E/", "x://y/");
232}
233
234/*
235 * "http://@foo" specifies an empty user name but does not specify a password.
236 * "http://foo" specifies neither a user name nor a password.
237 * So they should not be equivalent.
238 */
239void test_urlmatch_normalization__equivalents(void)
240{
241 compare_normalized_urls("httP://x", "Http://X/", 1);
242 compare_normalized_urls("Http://%4d%65:%4d^%70@The.Host", "hTTP://Me:%4D^p@the.HOST:80/", 1);
243 compare_normalized_urls("https://@x.y/^", "httpS://x.y:443/^", 0);
244 compare_normalized_urls("https://@x.y/^", "httpS://@x.y:0443/^", 1);
245 compare_normalized_urls("https://@x.y/^/../abc", "httpS://@x.y:0443/abc", 1);
246 compare_normalized_urls("https://@x.y/^/..", "httpS://@x.y:0443/", 1);
247}