summaryrefslogtreecommitdiff
path: root/utils
diff options
context:
space:
mode:
Diffstat (limited to 'utils')
-rw-r--r--utils/url.c33
1 files changed, 31 insertions, 2 deletions
diff --git a/utils/url.c b/utils/url.c
index 006b71f1e..1c587b86b 100644
--- a/utils/url.c
+++ b/utils/url.c
@@ -236,6 +236,7 @@ url_func_result url_join(const char *rel, const char *base, char **result)
path = base + base_match[5].rm_so;
path_len = base_match[5].rm_eo - base_match[5].rm_so;
+
/* 1) */
m = regexec(&url_re, rel, 10, rel_match, 0);
if (m) {
@@ -245,7 +246,6 @@ url_func_result url_join(const char *rel, const char *base, char **result)
/* 2) */
/* base + "#s" = (current document)#s (see Appendix C.1) */
- /** \todo does (current document) include the query? */
if (rel_match[9].rm_so != -1) {
fragment = rel + rel_match[9].rm_so;
fragment_len = rel_match[9].rm_eo - rel_match[9].rm_so;
@@ -254,6 +254,11 @@ url_func_result url_join(const char *rel, const char *base, char **result)
rel_match[2].rm_so == -1 &&
rel_match[4].rm_so == -1 &&
rel_match[6].rm_so == -1) {
+ if (base_match[7].rm_so != -1) {
+ query = base + base_match[7].rm_so;
+ query_len = base_match[7].rm_eo -
+ base_match[7].rm_so;
+ }
goto step7;
}
if (rel_match[7].rm_so != -1) {
@@ -261,6 +266,14 @@ url_func_result url_join(const char *rel, const char *base, char **result)
query_len = rel_match[7].rm_eo - rel_match[7].rm_so;
}
+ /* base + "?y" = (base - query)?y
+ * e.g http://a/b/c/d;p?q + ?y = http://a/b/c/d;p?y */
+ if (rel_match[5].rm_so == rel_match[5].rm_eo &&
+ rel_match[2].rm_so == -1 &&
+ rel_match[4].rm_so == -1 &&
+ rel_match[6].rm_so != -1)
+ goto step7;
+
/* 3) */
if (rel_match[2].rm_so != -1) {
scheme = rel + rel_match[2].rm_so;
@@ -334,8 +347,24 @@ url_func_result url_join(const char *rel, const char *base, char **result)
} else
path_len -= up_match[1].rm_eo - up_match[1].rm_so + 3;
}
+
+ /* and strip any remaining ../ | ./ pairs */
+ for (path = buf; path - buf < path_len; ) {
+ if (*path == '.' && path[1] == '.' && path[2] == '/') {
+ memmove(buf + (path - buf), path + 3,
+ ((buf + path_len) - path) - 3);
+ path_len -= 3;
+ }
+ else if (*path == '.' && path[1] == '/') {
+ memmove(buf + (path - buf), path + 2,
+ ((buf + path_len) - path) - 2);
+ path_len -= 2;
+ }
+ else
+ path++;
+ }
buf[path_len] = 0;
- path = buf;
+ path = buf;
step7: /* 7) */
(*result) = malloc(scheme_len + 1 + 2 + authority_len + path_len + 1 + 1 +