summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/libwebvi/urlutils.c29
-rw-r--r--tests/libwebvi_tests.c2
-rw-r--r--tests/urlutils_tests.c15
-rw-r--r--tests/urlutils_tests.h2
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