summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--render/form.c4
-rw-r--r--riscos/gui.c36
-rw-r--r--utils/url.c41
-rw-r--r--utils/url.h4
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);