1 /*****************************************************************************
2 * url.c: Test for url encoding/decoding stuff
3 *****************************************************************************
4 * Copyright (C) 2006 Rémi Denis-Courmont
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published by
8 * the Free Software Foundation; either version 2.1 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
19 *****************************************************************************/
29 #include <vlc_common.h>
31 #include <vlc_strings.h>
33 const char vlc_module_name
[] = "test_url";
35 static int exitcode
= 0;
37 static void test_compare(const char *in
, const char *exp
, const char *res
)
42 fprintf(stderr
, "\"%s\" returned NULL, expected \"%s\"\n",
50 fprintf(stderr
, "\"%s\" returned \"%s\", expected NULL\n",
54 fprintf(stderr
, "\"%s\" returned \"%s\", expected \"%s\"\n",
62 typedef char * (*conv_t
) (const char *);
64 static void test (conv_t f
, const char *in
, const char *out
)
67 test_compare(in
, out
, res
);
71 static inline void test_decode (const char *in
, const char *out
)
73 test (vlc_uri_decode_duplicate
, in
, out
);
76 static inline void test_b64 (const char *in
, const char *out
)
78 test(vlc_b64_encode
, in
, out
);
79 test(vlc_b64_decode
, out
, in
);
82 static char *make_URI_def (const char *in
)
84 return vlc_path2uri (in
, NULL
);
87 static inline void test_path (const char *in
, const char *out
)
89 test (make_URI_def
, in
, out
);
92 static inline void test_current_directory_path (const char *in
, const char *cwd
, const char *out
)
94 char *expected_result
;
95 int val
= asprintf (&expected_result
, "file://%s/%s", cwd
, out
);
99 test (make_URI_def
, in
, expected_result
);
100 free(expected_result
);
103 #define test_url_parse(in, protocol, user, pass, host, port, path, option) \
104 test_url_parse_internal(in, false, protocol, user, pass, host, port, path, option)
106 #define test_url_parse_fixup(in, protocol, user, pass, host, port, path, option) \
107 test_url_parse_internal(in, true, protocol, user, pass, host, port, path, option)
109 static void test_url_parse_internal(const char *in
, bool fixup
,
110 const char *protocol
,
111 const char *user
, const char *pass
,
112 const char *host
, unsigned port
,
113 const char *path
, const char *option
)
116 int ret
= fixup
? vlc_UrlParseFixup(&url
, in
) : vlc_UrlParse(&url
, in
);
118 /* XXX: only checking that the port-part is parsed correctly, and
119 * equal to 0, is currently not supported due to the below. */
120 if (protocol
== NULL
&& user
== NULL
&& pass
== NULL
&& host
== NULL
121 && port
== 0 && path
== NULL
&& option
== NULL
)
127 fprintf(stderr
, "\"%s\" accepted, expected rejection\n", in
);
133 test_compare(in
, protocol
, url
.psz_protocol
);
134 test_compare(in
, user
, url
.psz_username
);
135 test_compare(in
, pass
, url
.psz_password
);
137 if (ret
!= 0 && errno
== ENOSYS
)
139 test_compare(in
, NULL
, url
.psz_host
);
143 test_compare(in
, url
.psz_host
, host
);
145 if (url
.i_port
!= port
)
147 fprintf(stderr
, "\"%s\" returned %u, expected %u\n", in
, url
.i_port
,
152 test_compare(in
, path
, url
.psz_path
);
153 test_compare(in
, option
, url
.psz_option
);
157 static char *vlc_uri_resolve_rfc3986_test(const char *in
)
159 return vlc_uri_resolve("http://a/b/c/d;p?q", in
);
162 static void test_rfc3986(const char *reference
, const char *expected
)
164 test(vlc_uri_resolve_rfc3986_test
, reference
, expected
);
169 (void)setvbuf (stdout
, NULL
, _IONBF
, 0);
170 test_decode ("this_should_not_be_modified_1234",
171 "this_should_not_be_modified_1234");
173 test_decode ("This%20should%20be%20modified%201234!",
174 "This should be modified 1234!");
176 test_decode ("%7E", "~");
178 /* tests with invalid input */
179 test_decode ("%", NULL
);
180 test_decode ("%2", NULL
);
181 test_decode ("%0000", "");
183 /* Non-ASCII tests */
184 test_decode ("T%C3%a9l%c3%A9vision %e2%82%Ac", "Télévision €");
185 test_decode ("T%E9l%E9vision", "T\xe9l\xe9vision");
189 test_b64 ("f", "Zg==");
190 test_b64 ("fo", "Zm8=");
191 test_b64 ("foo", "Zm9v");
192 test_b64 ("foob", "Zm9vYg==");
193 test_b64 ("fooba", "Zm9vYmE=");
194 test_b64 ("foobar", "Zm9vYmFy");
199 test_path ("/", "file:///");
200 test_path ("/home/john/", "file:///home/john/");
201 test_path ("/home/john//too///many//slashes",
202 "file:///home/john//too///many//slashes");
203 test_path ("/home/john/music.ogg", "file:///home/john/music.ogg");
205 test_path ("C:\\", "file:///C:/");
206 test_path ("C:\\Users\\john\\", "file:///C:/Users/john/");
207 test_path ("C:\\Users\\john\\music.ogg",
208 "file:///C:/Users/john/music.ogg");
209 test_path ("\\\\server\\share\\dir\\file.ext",
210 "file://server/share/dir/file.ext");
213 /*int fd = open (".", O_RDONLY);
216 #ifndef _WIN32 /* FIXME: deal with anti-slashes */
224 char *tmpdir
= getcwd(buf
, ARRAY_SIZE (buf
));
231 test_current_directory_path ("movie.ogg", tmpdir
, "movie.ogg");
232 test_current_directory_path (".", tmpdir
, ".");
236 assert (val != -1);*/
238 /* URI to path tests */
239 #define test( a, b ) test (vlc_uri2path, a, b)
240 test ("mailto:john@example.com", NULL
);
241 test ("http://www.example.com/file.html#ref", NULL
);
242 test ("file://", NULL
);
244 test ("file:///", "/");
245 test ("file://localhost/home/john/music%2Eogg", "/home/john/music.ogg");
246 test ("file://localhost/home/john/text#ref", "/home/john/text");
247 test ("file://localhost/home/john/text?name=value", "/home/john/text");
248 test ("file://localhost/home/john/text?name=value#ref", "/home/john/text");
249 test ("file://?name=value", NULL
);
250 test ("file:///?name=value", "/");
251 test ("fd://0foobar", NULL
);
252 test ("fd://0#ref", "/dev/stdin");
253 test ("fd://1", "/dev/stdout");
254 test ("fd://12345", "/dev/fd/12345");
256 test ("file:///C:", "C:");
257 test ("file:///C:/Users/john/music%2Eogg", "C:\\Users\\john\\music.ogg");
258 test ("file://server/share/dir/file%2Eext",
259 "\\\\server\\share\\dir\\file.ext");
260 test ("file:///C:/Users/john/text#ref", "C:\\Users\\john\\text");
261 test ("file:///C:/Users/john/text?name=value", "C:\\Users\\john\\text");
262 test ("file:///C:/Users/john/text?name=value#ref",
263 "C:\\Users\\john\\text");
264 test ("file://?name=value", NULL
);
265 test ("file:///C:?name=value", "C:");
266 test ("fd://0foobar", NULL
);
267 test ("fd://0#ref", "CON");
268 test ("fd://1", "CON");
269 test ("fd://12345", NULL
);
273 test_url_parse("http://example.com", "http", NULL
, NULL
, "example.com", 0,
275 test_url_parse("http://example.com/", "http", NULL
, NULL
, "example.com", 0,
277 test_url_parse("http://[2001:db8::1]", "http", NULL
, NULL
, "2001:db8::1",
279 test_url_parse("http://example.com:", "http", NULL
, NULL
, "example.com", 0,
281 test_url_parse("protocol://john:doe@1.2.3.4:567", "protocol", "john", "doe", "1.2.3.4", 567, NULL
, NULL
);
282 test_url_parse("http://a.b/?opt=val", "http", NULL
, NULL
, "a.b", 0, "/", "opt=val");
283 test_url_parse("p://u:p@host:123/a/b/c?o=v", "p", "u", "p", "host", 123, "/a/b/c", "o=v");
284 test_url_parse("p://?o=v", "p", NULL
, NULL
, "", 0, NULL
, "o=v");
285 test_url_parse("p://h?o=v", "p", NULL
, NULL
, "h", 0, NULL
, "o=v");
286 test_url_parse("p://h:123?o=v", "p", NULL
, NULL
, "h", 123, NULL
, "o=v");
287 test_url_parse("p://u:p@h:123?o=v", "p", "u", "p", "h", 123, NULL
, "o=v");
288 test_url_parse("p://caf\xc3\xa9.example.com", "p", NULL
, NULL
,
289 "xn--caf-dma.example.com", 0, NULL
, NULL
);
290 test_url_parse("p://caf%C3%A9.example.com", "p", NULL
, NULL
,
291 "xn--caf-dma.example.com", 0, NULL
, NULL
);
292 test_url_parse("p://www.example.com/caf\xc3\xa9/", "p", NULL
, NULL
,
293 "www.example.com", 0, "/caf%C3%A9/", NULL
);
294 test_url_parse("p://h/white%20spaced", "p", NULL
, NULL
, "h", 0,
295 "/white%20spaced", NULL
);
297 test_url_parse("//example.com", NULL
, NULL
, NULL
, "example.com", 0,
299 test_url_parse("/file", NULL
, NULL
, NULL
, NULL
, 0, "/file", NULL
);
300 test_url_parse("?opt=val", NULL
, NULL
, NULL
, NULL
, 0, "", "opt=val");
301 test_url_parse("?o1=v1&o2=v2", NULL
, NULL
, NULL
, NULL
, 0, "",
303 test_url_parse("/f?o=v", NULL
, NULL
, NULL
, NULL
, 0, "/f", "o=v");
304 test_url_parse("//example.com/file", NULL
, NULL
, NULL
, "example.com", 0,
306 test_url_parse("//example.com?opt=val", NULL
, NULL
, NULL
, "example.com", 0,
308 test_url_parse("//example.com/f?o=v", NULL
, NULL
, NULL
, "example.com", 0,
311 test_url_parse("p://G a r b a g e", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
312 test_url_parse("p://h/G a r b a g e", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
313 test_url_parse("http://example.com:123xyz", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
314 test_url_parse("http://example.com: 123", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
315 test_url_parse("http://example.com:+123", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
316 test_url_parse("http://example.com:-123", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
317 test_url_parse("http://example.com:-4294967298", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
318 test_url_parse("http://example.com:-18446744073709551615", NULL
, NULL
, NULL
, NULL
, 0, NULL
, NULL
);
319 test_url_parse("http://user%/Oath", "http", NULL
, NULL
, NULL
, 0, "/Oath",
323 test_url_parse("smb://SERVER:445/SHARE/My file.mp3", "smb", NULL
, NULL
, "SERVER", 445, NULL
, NULL
);
324 test_url_parse_fixup("smb://SERVER:445/SHARE/My file.mp3", "smb", NULL
, NULL
, "SERVER", 445, "/SHARE/My%20file.mp3", NULL
);
326 /* Reference test cases for reference URI resolution */
327 static const char *rfc3986_cases
[] =
330 "g", "http://a/b/c/g",
331 "./g", "http://a/b/c/g",
332 "g/", "http://a/b/c/g/",
335 "?y", "http://a/b/c/d;p?y",
336 "g?y", "http://a/b/c/g?y",
337 //"#s", "http://a/b/c/d;p?q#s",
338 //"g#s", "http://a/b/c/g#s",
339 //"g?y#s", "http://a/b/c/g?y#s",
340 ";x", "http://a/b/c/;x",
341 "g;x", "http://a/b/c/g;x",
342 //"g;x?y#s", "http://a/b/c/g;x?y#s",
343 "", "http://a/b/c/d;p?q",
344 ".", "http://a/b/c/",
345 "./", "http://a/b/c/",
347 "../", "http://a/b/",
348 "../g", "http://a/b/g",
349 "../..", "http://a/",
350 "../../", "http://a/",
351 "../../g", "http://a/g",
353 "../../../g", "http://a/g",
354 "../../../../g", "http://a/g",
356 "/./g", "http://a/g",
357 "/../g", "http://a/g",
358 "g.", "http://a/b/c/g.",
359 ".g", "http://a/b/c/.g",
360 "g..", "http://a/b/c/g..",
361 "..g", "http://a/b/c/..g",
363 "./../g", "http://a/b/g",
364 "./g/.", "http://a/b/c/g/",
365 "g/./h", "http://a/b/c/g/h",
366 "g/../h", "http://a/b/c/h",
367 "g;x=1/./y", "http://a/b/c/g;x=1/y",
368 "g;x=1/../y", "http://a/b/c/y",
370 "g?y/./x", "http://a/b/c/g?y/./x",
371 "g?y/../x", "http://a/b/c/g?y/../x",
372 //"g#s/./x", "http://a/b/c/g#s/./x",
373 //"g#s/../x", "http://a/b/c/g#s/../x",
376 for (size_t i
= 0; i
< ARRAY_SIZE(rfc3986_cases
); i
+= 2)
377 test_rfc3986(rfc3986_cases
[i
], rfc3986_cases
[i
+ 1]);
379 /* Check that fixup does not mangle valid URIs */
380 static const char *valid_uris
[] =
383 ".", "..", "/", "../../dir/subdir/subsubdir/file.ext",
384 "//example.com?q=info",
385 "//192.0.2.1/index.html",
386 "//[2001:db8::1]/index.html",
387 "https://www.example.com:8443/?opt1=val1&opt2=val2",
388 "https://192.0.2.1:8443/#foobar",
389 "https://[2001:db8::1]:8443/file?opt=val#foobar",
390 "https://[v9.abcd:efgh]:8443/welcome?to=the#future",
391 "mailto:john@example.com",
392 "mailto:mailman@example.com?subject=help",
393 "mailto:mailman@example.com?body=subscribe%20news-flash",
394 "mailto:literal@[192.0.2.1],literal@[IPv6:2001:db8::1]",
397 for (size_t i
= 0; i
< ARRAY_SIZE(valid_uris
); i
++)
398 test(vlc_uri_fixup
, valid_uris
[i
], valid_uris
[i
]);
400 /* Check how invalid URIs are fixed up */
401 static const char *invalid_uris
[][2] =
403 { "Hello world.txt", "Hello%20world.txt" },
404 { "Café", "Caf%C3%A9" },
405 { "100%", "100%25" },
406 { "//[1.2.3.4]/[Foo]", "//[1.2.3.4]/%5BFoo%5D" },
407 { "/[Bar]", "/%5BBar%5D" },
408 { "http://localhost/[Baz]", "http://localhost/%5BBaz%5D" },
411 for (size_t i
= 0; i
< ARRAY_SIZE(invalid_uris
); i
++)
412 test(vlc_uri_fixup
, invalid_uris
[i
][0], invalid_uris
[i
][1]);