diff options
-rw-r--r-- | src/libwebvi/urlutils.c | 29 | ||||
-rw-r--r-- | tests/libwebvi_tests.c | 2 | ||||
-rw-r--r-- | tests/urlutils_tests.c | 15 | ||||
-rw-r--r-- | tests/urlutils_tests.h | 2 |
4 files changed, 42 insertions, 6 deletions
diff --git a/src/libwebvi/urlutils.c b/src/libwebvi/urlutils.c index de64e06..3b4c1b4 100644 --- a/src/libwebvi/urlutils.c +++ b/src/libwebvi/urlutils.c @@ -3,11 +3,15 @@ static const gchar *skip_scheme(const char *url); static gboolean is_scheme_character(gchar c); +static gboolean has_scheme(const gchar *url); gchar *relative_url_to_absolute(const gchar *baseurl, const gchar *href) { gchar *absolute; gchar *prefix; const gchar *postfix = href; + if (!href || !baseurl) + return NULL; + if ((href[0] == '/') && (href[1] == '/')) { gchar *scheme = url_scheme(baseurl); prefix = g_strconcat(scheme, ":", NULL); @@ -21,7 +25,7 @@ gchar *relative_url_to_absolute(const gchar *baseurl, const gchar *href) { prefix = url_path_including_file(baseurl); } else if (href[0] =='#') { prefix = url_path_and_query(baseurl); - } else if (strstr(href, "://") == NULL) { + } else if (!has_scheme(href)) { prefix = url_path_dirname(baseurl); } else { // href is absolute @@ -44,13 +48,19 @@ gchar *url_scheme(const gchar *url) { const gchar *scheme_end = skip_scheme(url); if (scheme_end == url) { - // no scheme + /* no scheme */ return g_strdup(""); } else { - // scheme found - // Do not include :// in the return value - g_assert(scheme_end >= url+3); - return g_strndup(url, scheme_end-3 - url); + /* scheme found */ + /* Do not include the scheme postfix, which is either :// or : */ + int scheme_postfix_len; + if ((scheme_end >= url+3) && (strncmp(scheme_end-3, "://", 3) == 0)) { + scheme_postfix_len = 3; + } else { + g_assert((scheme_end >= url+1) && (scheme_end[-1] == ':')); + scheme_postfix_len = 1; + } + return g_strndup(url, scheme_end - scheme_postfix_len - url); } } @@ -112,6 +122,10 @@ gchar *url_path_and_query(const gchar *url) { return g_strndup(url, end - url); } +gboolean has_scheme(const gchar *url) { + return skip_scheme(url) != url; +} + const gchar *skip_scheme(const char *url) { const gchar *c = url; while (is_scheme_character(*c)) { @@ -121,6 +135,9 @@ const gchar *skip_scheme(const char *url) { if (strncmp(c, "://", 3) == 0) { // scheme found return c + 3; + } else if (c[0] == ':') { + // scheme without // such as mailto: + return c + 1; } else { // schemeless url return url; diff --git a/tests/libwebvi_tests.c b/tests/libwebvi_tests.c index f7975af..0e50e15 100644 --- a/tests/libwebvi_tests.c +++ b/tests/libwebvi_tests.c @@ -76,6 +76,7 @@ int main(int argc, char** argv) g_test_add_func("/urlutils/scheme_double", test_url_scheme_double_scheme); g_test_add_func("/urlutils/scheme_invalid_characters", test_url_scheme_invalid_characters); + g_test_add_func("/urlutils/scheme_mailto", test_url_scheme_mailto); g_test_add_func("/urlutils/root", test_url_root); g_test_add_func("/urlutils/root_path", test_url_root_full_path); g_test_add_func("/urlutils/root_query", test_url_root_terminated_by_query); @@ -109,6 +110,7 @@ int main(int argc, char** argv) g_test_add_func("/urlutils/rel2abs_append_fragment", test_url_rel2abs_append_fragment); g_test_add_func("/urlutils/rel2abs_scheme", test_url_rel2abs_scheme); + g_test_add_func("/urlutils/rel2abs_mailto", test_url_rel2abs_mailto_scheme); return g_test_run(); } diff --git a/tests/urlutils_tests.c b/tests/urlutils_tests.c index da5f9e1..73e76ff 100644 --- a/tests/urlutils_tests.c +++ b/tests/urlutils_tests.c @@ -29,6 +29,13 @@ void test_url_scheme_invalid_characters() { g_free(prefix); } +void test_url_scheme_mailto() { + gchar *prefix = url_scheme("mailto:john.doe@example.com"); + g_assert(prefix); + g_assert(strcmp(prefix, "mailto") == 0); + g_free(prefix); +} + void test_url_root() { gchar *prefix = url_root("http://example.com/"); g_assert(prefix); @@ -225,3 +232,11 @@ void test_url_rel2abs_scheme() { g_assert(strcmp(abs, "http://server.org/path2/file2") == 0); g_free(abs); } + +void test_url_rel2abs_mailto_scheme() { + gchar *abs = relative_url_to_absolute("http://example.com/index.html", + "mailto:john.doe@example.com"); + g_assert(abs); + g_assert(strcmp(abs, "mailto:john.doe@example.com") == 0); + g_free(abs); +} diff --git a/tests/urlutils_tests.h b/tests/urlutils_tests.h index e4c796c..28c44ba 100644 --- a/tests/urlutils_tests.h +++ b/tests/urlutils_tests.h @@ -7,6 +7,7 @@ void test_url_scheme(); void test_url_scheme_no_scheme(); void test_url_scheme_double_scheme(); void test_url_scheme_invalid_characters(); +void test_url_scheme_mailto(); void test_url_root(); void test_url_root_full_path(); void test_url_root_terminated_by_query(); @@ -34,5 +35,6 @@ void test_url_rel2abs_append_query(); void test_url_rel2abs_fragment(); void test_url_rel2abs_append_fragment(); void test_url_rel2abs_scheme(); +void test_url_rel2abs_mailto_scheme(); #endif // URLUTILS_TESTS_H |