From 0d39c69763f7918fdd884516140e23b4eab51b10 Mon Sep 17 00:00:00 2001 From: John Tytgat Date: Wed, 2 Apr 2008 00:43:51 +0000 Subject: [PATCH] - riscos/gui.c(path_to_url): escape the characters which need to be escaped when converting the host path to file: URL. - utils/{url.c,url.h}(url_escape): * added parameter 'toskip' to specify number of input characters which need to be skipped in the escape process. This avoids extra malloc buffer juggling. * added parameter 'escexceptions' to specify the characters which need to be excluded from the escape process. Solves SF tracker ID 1910169. Note that when discname in path contains '/' characters (case: "file:///Sunfish#192.168.0.50::/home/joty.$/jo.html") or there is no discname specified at all (case "file:///HostFS:$/jo.htm"), you need an UnixLib fix as in http://www.riscos.info/websvn/listing.php?repname=gccsdk&path=%2Ftrunk%2Fgcc4%2F&rev=3395&sc=1 svn path=/trunk/netsurf/; revision=4069 --- render/form.c | 4 ++-- riscos/gui.c | 36 ++++++++++++++++++++++++++---------- utils/url.c | 41 ++++++++++++++++++++++++----------------- utils/url.h | 4 ++-- 4 files changed, 54 insertions(+), 31 deletions(-) diff --git a/render/form.c b/render/form.c index d99205047..4ed0e4f88 100644 --- a/render/form.c +++ b/render/form.c @@ -564,7 +564,7 @@ char *form_url_encode(struct form *form, s[0] = 0; for (; control; control = control->next) { - url_err = url_escape(control->name, true, &name); + url_err = url_escape(control->name, 0, true, NULL, &name); if (url_err == URL_FUNC_NOMEM) { free(s); return 0; @@ -572,7 +572,7 @@ char *form_url_encode(struct form *form, assert(url_err == URL_FUNC_OK); - url_err = url_escape(control->value, true, &value); + url_err = url_escape(control->value, 0, true, NULL, &value); if (url_err == URL_FUNC_NOMEM) { free(name); free(s); diff --git a/riscos/gui.c b/riscos/gui.c index dfb0520f3..f7173fe81 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -1965,16 +1965,16 @@ void ro_msg_window_info(wimp_message *message) char *path_to_url(const char *path) { int spare; - char *buffer = 0; - char *url = 0; + char *buffer, *url, *escurl; os_error *error; + url_func_result url_err; error = xosfscontrol_canonicalise_path(path, 0, 0, 0, 0, &spare); if (error) { LOG(("xosfscontrol_canonicalise_path failed: 0x%x: %s", error->errnum, error->errmess)); warn_user("PathToURL", error->errmess); - return 0; + return NULL; } buffer = malloc(1 - spare); @@ -1984,7 +1984,7 @@ char *path_to_url(const char *path) warn_user("NoMemory", 0); free(buffer); free(url); - return 0; + return NULL; } error = xosfscontrol_canonicalise_path(path, buffer, 0, 0, 1 - spare, @@ -1995,14 +1995,30 @@ char *path_to_url(const char *path) warn_user("PathToURL", error->errmess); free(buffer); free(url); - return 0; + return NULL; } - strcpy(url, "file://"); - __unixify(buffer, __RISCOSIFY_NO_REVERSE_SUFFIX, url + 7, - 1 - spare + 3 /* 10 - "file://" */, 0); - free(buffer); - return url; + memcpy(url, "file://", sizeof("file://")-1); + if (__unixify(buffer, __RISCOSIFY_NO_REVERSE_SUFFIX, + url + sizeof("file://")-1, + 1 - spare + 10 - (sizeof("file://")-1), + 0) == NULL) { + LOG(("__unixify failed: %s", buffer)); + free(buffer); + free(url); + return NULL; + } + free(buffer); buffer = NULL; + + /* We don't want '/' to be escaped. */ + url_err = url_escape(url, sizeof("file://")-1, false, "/", &escurl); + free(url); url = NULL; + if (url_err != URL_FUNC_OK) { + LOG(("url_escape failed: %s", url)); + return NULL; + } + + return escurl; } diff --git a/utils/url.c b/utils/url.c index cc7a76215..b272a903a 100644 --- a/utils/url.c +++ b/utils/url.c @@ -871,17 +871,19 @@ no_path: /** * Escape a string suitable for inclusion in an URL. * - * \param unescaped the unescaped string - * \param sptoplus true iff spaces should be converted to + - * \param result pointer to pointer to buffer to hold escaped string + * \param unescaped the unescaped string + * \param toskip number of bytes to skip in unescaped string + * \param sptoplus true iff spaces should be converted to + + * \param escexceptions NULL or a string of characters excluded to be escaped + * \param result pointer to pointer to buffer to hold escaped string * \return URL_FUNC_OK on success */ -url_func_result url_escape(const char *unescaped, bool sptoplus, - char **result) +url_func_result url_escape(const char *unescaped, size_t toskip, + bool sptoplus, const char *escexceptions, char **result) { - int len; - char *escaped, *d; + size_t len; + char *escaped, *d, *tmpres; const char *c; if (!unescaped || !result) @@ -890,21 +892,25 @@ url_func_result url_escape(const char *unescaped, bool sptoplus, *result = NULL; len = strlen(unescaped); + if (len < toskip) + return URL_FUNC_FAILED; + len -= toskip; escaped = malloc(len * 3 + 1); if (!escaped) return URL_FUNC_NOMEM; - for (c = unescaped, d = escaped; *c; c++) { + for (c = unescaped + toskip, d = escaped; *c; c++) { /* Check if we should escape this byte. * '~' is unreserved and should not be percent encoded, if * you believe the spec; however, leaving it unescaped * breaks a bunch of websites, so we escape it anyway. */ - if (!isascii(*c) || strchr(":/?#[]@" /* gen-delims */ - "!$&'()*+,;=" /* sub-delims */ - "<>%\"{}|\\^`~", /* others */ - *c) || - *c <= 0x20 || *c == 0x7f) { + if (!isascii(*c) + || (strchr(":/?#[]@" /* gen-delims */ + "!$&'()*+,;=" /* sub-delims */ + "<>%\"{}|\\^`~" /* others */, *c) + && (!escexceptions || !strchr(escexceptions, *c))) + || *c <= 0x20 || *c == 0x7f) { if (*c == 0x20 && sptoplus) { *d++ = '+'; } else { @@ -917,16 +923,17 @@ url_func_result url_escape(const char *unescaped, bool sptoplus, *d++ = *c; } } - *d++ = '\0'; - (*result) = malloc(d - escaped); - if (!(*result)) { + tmpres = malloc(d - escaped + toskip); + if (!tmpres) { free(escaped); return URL_FUNC_NOMEM; } - memcpy((*result), escaped, d - escaped); + memcpy(tmpres, unescaped, toskip); + memcpy(tmpres + toskip, escaped, d - escaped); + *result = tmpres; free(escaped); diff --git a/utils/url.h b/utils/url.h index 9a1b934a5..f83c626f6 100644 --- a/utils/url.h +++ b/utils/url.h @@ -47,8 +47,8 @@ url_func_result url_host(const char *url, char **result); url_func_result url_scheme(const char *url, char **result); url_func_result url_nice(const char *url, char **result, bool remove_extensions); -url_func_result url_escape(const char *unescaped, bool sptoplus, - char **result); +url_func_result url_escape(const char *unescaped, size_t toskip, + bool sptoplus, const char *escexceptions, char **result); url_func_result url_canonical_root(const char *url, char **result); url_func_result url_parent(const char *url, char **result); url_func_result url_plq(const char *url, char **result);