/*****************************************************************************
* url.c: Test for url encoding/decoding stuff
*****************************************************************************
* Copyright (C) 2006 Rémi Denis-Courmont
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
*****************************************************************************/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <vlc_common.h>
#include <vlc_url.h>
#include <vlc_strings.h>
const char vlc_module_name[] = "test_url";
static int exitcode = 0;
static void test_compare( const char *in, const char *exp, const char *res)
{
if (res == NULL)
{
if (exp != NULL)
fprintf(stderr, "\"%s\ " returned NULL, expected \"%s\ "\n",
in, exp);
else
return;
}
else
{
if (exp == NULL)
fprintf(stderr, "\"%s\ " returned \"%s\ ", expected NULL\n",
in, res);
else
if (strcmp(res, exp))
fprintf(stderr, "\"%s\ " returned \"%s\ ", expected \"%s\ "\n",
in, res, exp);
else
return;
}
exit( 2);
}
typedef char * (*conv_t) ( const char *);
static void test (conv_t f, const char *in, const char *out)
{
char *res = f(in);
test_compare(in, out, res);
free(res);
}
static inline void test_decode ( const char *in, const char *out)
{
test (vlc_uri_decode_duplicate, in, out);
}
static inline void test_b64 ( const char *in, const char *out)
{
test(vlc_b64_encode, in, out);
test(vlc_b64_decode, out, in);
}
static char *make_URI_def ( const char *in)
{
return vlc_path2uri (in, NULL);
}
static inline void test_path ( const char *in, const char *out)
{
test (make_URI_def, in, out);
}
static inline void test_current_directory_path ( const char *in, const char *cwd, const char *out)
{
char *expected_result;
int val = asprintf (&expected_result, "file://%s/%s", cwd, out);
if (val < 0)
abort();
test (make_URI_def, in, expected_result);
free(expected_result);
}
#define test_url_parse(in, protocol, user, pass, host, port, path, option) \
test_url_parse_internal(in, false, protocol, user, pass, host, port, path, option)
#define test_url_parse_fixup(in, protocol, user, pass, host, port, path, option) \
test_url_parse_internal(in, true, protocol, user, pass, host, port, path, option)
static void test_url_parse_internal(const char *in, bool fixup,
const char *protocol,
const char *user, const char *pass,
const char *host, unsigned port,
const char *path, const char *option)
{
vlc_url_t url;
int ret = fixup ? vlc_UrlParseFixup(&url, in) : vlc_UrlParse(&url, in);
/* XXX: only checking that the port-part is parsed correctly, and
* equal to 0, is currently not supported due to the below. */
if (protocol == NULL && user == NULL && pass == NULL && host == NULL
&& port == 0 && path == NULL && option == NULL)
{
vlc_UrlClean(&url);
if (ret != -1)
{
fprintf(stderr, "\"%s\" accepted, expected rejection\n", in);
exit(2);
}
return;
}
test_compare(in, protocol, url.psz_protocol);
test_compare(in, user, url.psz_username);
test_compare(in, pass, url.psz_password);
if (ret != 0 && errno == ENOSYS)
{
test_compare(in, NULL, url.psz_host);
exitcode = 77;
}
else
test_compare(in, url.psz_host, host);
if (url.i_port != port)
{
fprintf(stderr, "\"%s\" returned %u, expected %u\n", in, url.i_port,
port);
exit(2);
}
test_compare(in, path, url.psz_path);
test_compare(in, option, url.psz_option);
vlc_UrlClean(&url);
}
static char *vlc_uri_resolve_rfc3986_test(const char *in)
{
return vlc_uri_resolve("http://a/b/c/d;p?q", in);
}
static void test_rfc3986(const char *reference, const char *expected)
{
test(vlc_uri_resolve_rfc3986_test, reference, expected);
}
int main (void)
{
(void)setvbuf (stdout, NULL, _IONBF, 0);
test_decode ("this_should_not_be_modified_1234",
"this_should_not_be_modified_1234");
test_decode ("This%20should%20be%20modified%201234!",
"This should be modified 1234!");
test_decode ("%7E", "~");
/* tests with invalid input */
test_decode ("%", NULL);
test_decode ("%2", NULL);
test_decode ("%0000", "");
/* Non-ASCII tests */
test_decode ("T%C3%a9l%c3%A9vision %e2%82%Ac", "Télévision €");
test_decode ("T%E9l%E9vision", "T\xe9l\xe9vision");
/* Base 64 tests */
test_b64 ("", "");
test_b64 ("f", "Zg==");
test_b64 ("fo", "Zm8=");
test_b64 ("foo", "Zm9v");
test_b64 ("foob", "Zm9vYg==");
test_b64 ("fooba", "Zm9vYmE=");
test_b64 ("foobar", "Zm9vYmFy");
/* Path test */
test_path("", NULL);
#ifndef _WIN32
test_path ("/", "file:///");
test_path ("/home/john/", "file:///home/john/");
test_path ("/home/john//too///many//slashes",
"file:///home/john//too///many//slashes");
test_path ("/home/john/music.ogg", "file:///home/john/music.ogg");
#else
test_path ("C:\\", "file:///C:/");
test_path ("C:\\Users\\john\\", "file:///C:/Users/john/");
test_path ("C:\\Users\\john\\music.ogg",
"file:///C:/Users/john/music.ogg");
test_path ("\\\\server\\share\\dir\\file.ext",
"file://server/share/dir/file.ext");
#endif
/*int fd = open (".", O_RDONLY);
assert (fd != -1);*/
#ifndef _WIN32 /* FIXME: deal with anti-slashes */
if (chdir ("/tmp"))
{
perror("/tmp");
exit(1);
}
char buf[256];
char *tmpdir = getcwd(buf, ARRAY_SIZE (buf));
if (tmpdir == NULL)
{
perror("getcwd");
exit(1);
}
test_current_directory_path ("movie.ogg", tmpdir, "movie.ogg");
test_current_directory_path (".", tmpdir, ".");
#endif
/*val = fchdir (fd);
assert (val != -1);*/
/* URI to path tests */
#define test( a, b ) test (vlc_uri2path, a, b)
test ("mailto:john@example.com", NULL);
test ("http://www.example.com/file.html#ref", NULL);
test ("file://", NULL);
#ifndef _WIN32
test ("file:///", "/");
test ("file://localhost/home/john/music%2Eogg", "/home/john/music.ogg");
test ("file://localhost/home/john/text#ref", "/home/john/text");
test ("file://localhost/home/john/text?name=value", "/home/john/text");
test ("file://localhost/home/john/text?name=value#ref", "/home/john/text");
test ("file://?name=value", NULL);
test ("file:///?name=value", "/");
test ("fd://0foobar", NULL);
test ("fd://0#ref", "/dev/stdin");
test ("fd://1", "/dev/stdout");
test ("fd://12345", "/dev/fd/12345");
#else
test ("file:///C:", "C:");
test ("file:///C:/Users/john/music%2Eogg", "C:\\Users\\john\\music.ogg");
test ("file://server/share/dir/file%2Eext",
"\\\\server\\share\\dir\\file.ext");
test ("file:///C:/Users/john/text#ref", "C:\\Users\\john\\text");
test ("file:///C:/Users/john/text?name=value", "C:\\Users\\john\\text");
test ("file:///C:/Users/john/text?name=value#ref",
"C:\\Users\\john\\text");
test ("file://?name=value", NULL);
test ("file:///C:?name=value", "C:");
test ("fd://0foobar", NULL);
test ("fd://0#ref", "CON");
test ("fd://1", "CON");
test ("fd://12345", NULL);
#endif
#undef test
test_url_parse("http://example.com", "http", NULL, NULL, "example.com", 0,
NULL, NULL);
test_url_parse("http://example.com/", "http", NULL, NULL, "example.com", 0,
"/", NULL);
test_url_parse("http://[2001:db8::1]", "http", NULL, NULL, "2001:db8::1",
0, NULL, NULL);
test_url_parse("http://example.com:", "http", NULL, NULL, "example.com", 0,
NULL, NULL);
test_url_parse("protocol://john:doe@1.2.3.4:567", "protocol", "john", "doe", "1.2.3.4", 567, NULL, NULL);
test_url_parse("http://a.b/?opt=val", "http", NULL, NULL, "a.b", 0, "/", "opt=val");
test_url_parse("p://u:p@host:123/a/b/c?o=v", "p", "u", "p", "host", 123, "/a/b/c", "o=v");
test_url_parse("p://?o=v", "p", NULL, NULL, "", 0, NULL, "o=v");
test_url_parse("p://h?o=v", "p", NULL, NULL, "h", 0, NULL, "o=v");
test_url_parse("p://h:123?o=v", "p", NULL, NULL, "h", 123, NULL, "o=v");
test_url_parse("p://u:p@h:123?o=v", "p", "u", "p", "h", 123, NULL, "o=v");
test_url_parse("p://caf\xc3\xa9.example.com", "p", NULL, NULL,
"xn--caf-dma.example.com", 0, NULL, NULL);
test_url_parse("p://caf%C3%A9.example.com", "p", NULL, NULL,
"xn--caf-dma.example.com", 0, NULL, NULL);
test_url_parse("p://www.example.com/caf\xc3\xa9/", "p", NULL, NULL,
"www.example.com", 0, "/caf%C3%A9/", NULL);
test_url_parse("p://h/white%20spaced", "p", NULL, NULL, "h", 0,
"/white%20spaced", NULL);
test_url_parse("p://h/[hello:world]", "p", NULL, NULL, "h", 0,
"/[hello:world]", NULL);
/* Relative URIs */
test_url_parse("//example.com", NULL, NULL, NULL, "example.com", 0,
NULL, NULL);
test_url_parse("/file", NULL, NULL, NULL, NULL, 0, "/file", NULL);
test_url_parse("?opt=val", NULL, NULL, NULL, NULL, 0, "", "opt=val");
test_url_parse("?o1=v1&o2=v2", NULL, NULL, NULL, NULL, 0, "",
"o1=v1&o2=v2");
test_url_parse("/f?o=v", NULL, NULL, NULL, NULL, 0, "/f", "o=v");
test_url_parse("//example.com/file", NULL, NULL, NULL, "example.com", 0,
"/file", NULL);
test_url_parse("//example.com?opt=val", NULL, NULL, NULL, "example.com", 0,
NULL, "opt=val");
test_url_parse("//example.com/f?o=v", NULL, NULL, NULL, "example.com", 0,
"/f", "o=v");
/* Invalid URIs */
test_url_parse("p://G a r b a g e", NULL, NULL, NULL, NULL, 0, NULL, NULL);
test_url_parse("p://h/G a r b a g e", NULL, NULL, NULL, NULL, 0, NULL, NULL);
test_url_parse("http://example.com:123xyz", NULL, NULL, NULL, NULL, 0, NULL, NULL);
test_url_parse("http://example.com: 123", NULL, NULL, NULL, NULL, 0, NULL, NULL );
test_url_parse("http://example.com:+123", NULL, NULL, NULL, NULL, 0, NULL, NULL );
test_url_parse("http://example.com:-123", NULL, NULL, NULL, NULL, 0, NULL, NULL );
test_url_parse("http://example.com:-4294967298", NULL, NULL, NULL, NULL, 0, NULL, NULL );
test_url_parse("http://example.com:-18446744073709551615", NULL, NULL, NULL, NULL, 0, NULL, NULL );
test_url_parse("http://user%/Oath", "http", NULL, NULL, NULL, 0, "/Oath",
NULL);
/* URIs to fixup */
test_url_parse("smb://SERVER:445/SHARE/My file.mp3", "smb", NULL, NULL, "SERVER", 445, NULL, NULL);
test_url_parse_fixup("smb://SERVER:445/SHARE/My file.mp3", "smb", NULL, NULL, "SERVER", 445, "/SHARE/My%20file.mp3", NULL);
/* Reference test cases for reference URI resolution */
static const char *rfc3986_cases[] =
{
"g:h", "g:h",
"g", "http://a/b/c/g",
"./g", "http://a/b/c/g",
"g/", "http://a/b/c/g/",
"/g", "http://a/g",
"//g", "http://g",
"?y", "http://a/b/c/d;p?y",
"g?y", "http://a/b/c/g?y",
//"#s", "http://a/b/c/d;p?q#s",
//"g#s", "http://a/b/c/g#s",
//"g?y#s", "http://a/b/c/g?y#s",
";x", "http://a/b/c/;x",
"g;x", "http://a/b/c/g;x",
//"g;x?y#s", "http://a/b/c/g;x?y#s",
"", "http://a/b/c/d;p?q",
".", "http://a/b/c/",
"./", "http://a/b/c/",
"..", "http://a/b/",
"../", "http://a/b/",
"../g", "http://a/b/g",
"../..", "http://a/",
"../../", "http://a/",
"../../g", "http://a/g",
"../../../g", "http://a/g",
"../../../../g", "http://a/g",
"/./g", "http://a/g",
"/../g", "http://a/g",
"g.", "http://a/b/c/g.",
".g", "http://a/b/c/.g",
"g..", "http://a/b/c/g..",
"..g", "http://a/b/c/..g",
"./../g", "http://a/b/g",
"./g/.", "http://a/b/c/g/",
"g/./h", "http://a/b/c/g/h",
"g/../h", "http://a/b/c/h",
"g;x=1/./y", "http://a/b/c/g;x=1/y",
"g;x=1/../y", "http://a/b/c/y",
"g?y/./x", "http://a/b/c/g?y/./x",
"g?y/../x", "http://a/b/c/g?y/../x",
//"g#s/./x", "http://a/b/c/g#s/./x",
//"g#s/../x", "http://a/b/c/g#s/../x",
};
for (size_t i = 0; i < ARRAY_SIZE(rfc3986_cases); i += 2)
test_rfc3986(rfc3986_cases[i], rfc3986_cases[i + 1]);
/* Check that fixup does not mangle valid URIs */
static const char *valid_uris[] =
{
"#href", "?opt=val",
".", "..", "/", "../../dir/subdir/subsubdir/file.ext",
"//example.com?q=info",
"//192.0.2.1/index.html",
"//[2001:db8::1]/index.html",
"https://www.example.com:8443/?opt1=val1&opt2=val2",
"https://192.0.2.1:8443/#foobar",
"https://[2001:db8::1]:8443/file?opt=val#foobar",
"https://[v9.abcd:efgh]:8443/welcome?to=the#future",
"mailto:john@example.com",
"mailto:mailman@example.com?subject=help",
"mailto:mailman@example.com?body=subscribe%20news-flash",
"mailto:literal@[192.0.2.1],literal@[IPv6:2001:db8::1]",
};
for (size_t i = 0; i < ARRAY_SIZE(valid_uris); i++)
test(vlc_uri_fixup, valid_uris[i], valid_uris[i]);
/* Check how invalid URIs are fixed up */
static const char *invalid_uris[][2] =
{
{ "Hello world.txt", "Hello%20world.txt" },
{ "Café", "Caf%C3%A9" },
{ "100%", "100%25" },
{ "//[1.2.3.4]/[Foo]", "//[1.2.3.4]/%5BFoo%5D" },
{ "/[Bar]", "/%5BBar%5D" },
{ "http://localhost/[Baz]", "http://localhost/%5BBaz%5D" },
};
for (size_t i = 0; i < ARRAY_SIZE(invalid_uris); i++)
test(vlc_uri_fixup, invalid_uris[i][0], invalid_uris[i][1]);
return exitcode;
}
¤ Dauer der Verarbeitung: 0.2 Sekunden
(vorverarbeitet am 2026-11-04)
¤
*© Formatika GbR, Deutschland
|
|