URL escape: Simplify to avoid unnecessary allocation.

This removes the toskip parameter, which was only used by the RISC OS
front end.  The toskip param was used to skip 8 characters which did
not need to be escaped from the start of the URL.  The RISC OS front
end now orders the steps of its URL construction to avoid the need
for this.
This commit is contained in:
Michael Drake 2016-07-24 21:00:29 +01:00
parent 7bff70e746
commit a122b94efd
7 changed files with 60 additions and 61 deletions

View File

@ -240,7 +240,7 @@ make_search_nsurl(struct search_provider *provider,
size_t urlstr_len;
/* escape the search term and join it to the search url */
ret = url_escape(term, 0, true, NULL, &eterm);
ret = url_escape(term, true, NULL, &eterm);
if (ret != NSERROR_OK) {
return ret;
}

View File

@ -193,7 +193,7 @@ static nserror atari_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
ret = url_escape(path, 0, false, "/", &escpath);
ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}

View File

@ -1405,7 +1405,7 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
int spare;
char *canonical_path; /* canonicalised RISC OS path */
char *unix_path; /* unix path */
char *escurl;
char *escaped_path;
os_error *error;
nserror ret;
int urllen;
@ -1443,31 +1443,34 @@ static nserror ro_path_to_nsurl(const char *path, struct nsurl **url_out)
}
free(canonical_path);
/* convert the unix path into a url */
urllen = strlen(unix_path) + FILE_SCHEME_PREFIX_LEN + 1;
url = malloc(urllen);
if (url == NULL) {
LOG("Unable to allocate url");
/* url escape the unix path */
ret = url_escape(unix_path, false, "/", &escaped_path);
if (ret != NSERROR_OK) {
free(unix_path);
return NSERROR_NOMEM;
}
if (*unix_path == '/') {
snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path + 1);
} else {
snprintf(url, urllen, "%s%s", FILE_SCHEME_PREFIX, unix_path);
return ret;
}
free(unix_path);
/* We don't want '/' to be escaped. */
ret = url_escape(url, FILE_SCHEME_PREFIX_LEN, false, "/", &escurl);
free(url);
if (ret != NSERROR_OK) {
return ret;
/* convert the escaped unix path into a url */
urllen = strlen(escaped_path) + FILE_SCHEME_PREFIX_LEN + 1;
url = malloc(urllen);
if (url == NULL) {
LOG("Unable to allocate url");
free(escaped_path);
return NSERROR_NOMEM;
}
ret = nsurl_create(escurl, url_out);
free(escurl);
if (*escaped_path == '/') {
snprintf(url, urllen, "%s%s",
FILE_SCHEME_PREFIX, escaped_path + 1);
} else {
snprintf(url, urllen, "%s%s",
FILE_SCHEME_PREFIX, escaped_path);
}
free(escaped_path);
ret = nsurl_create(url, url_out);
free(url);
return ret;
}

View File

@ -912,7 +912,7 @@ static char *form_url_encode(struct form *form,
}
for (; control; control = control->next) {
url_err = url_escape(control->name, 0, true, NULL, &name);
url_err = url_escape(control->name, true, NULL, &name);
if (url_err == NSERROR_NOMEM) {
free(s);
return NULL;
@ -920,7 +920,7 @@ static char *form_url_encode(struct form *form,
assert(url_err == NSERROR_OK);
url_err = url_escape(control->value, 0, true, NULL, &value);
url_err = url_escape(control->value, true, NULL, &value);
if (url_err == NSERROR_NOMEM) {
free(name);
free(s);

View File

@ -174,7 +174,7 @@ static nserror posix_path_to_nsurl(const char *path, struct nsurl **url_out)
}
/* escape the path so it can be placed in a url */
ret = url_escape(path, 0, false, "/", &escpath);
ret = url_escape(path, false, "/", &escpath);
if (ret != NSERROR_OK) {
return ret;
}

View File

@ -113,63 +113,60 @@ nserror url_unescape(const char *str, size_t length,
/* exported interface documented in utils/url.h */
nserror url_escape(const char *unescaped, size_t toskip,
bool sptoplus, const char *escexceptions, char **result)
nserror url_escape(const char *unescaped, bool sptoplus,
const char *escexceptions, char **result)
{
size_t len;
char *escaped, *d, *tmpres;
size_t len, new_len;
char *escaped, *pos;
const char *c;
if (!unescaped || !result)
if (unescaped == NULL || result == NULL) {
return NSERROR_NOT_FOUND;
*result = NULL;
}
len = strlen(unescaped);
if (len < toskip)
return NSERROR_NOT_FOUND;
len -= toskip;
escaped = malloc(len * 3 + 1);
if (!escaped)
if (escaped == NULL) {
return NSERROR_NOMEM;
}
pos = escaped;
for (c = unescaped + toskip, d = escaped; *c; c++) {
for (c = unescaped; *c != '\0'; 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)
&& (!escexceptions || !strchr(escexceptions, *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++ = '+';
*pos++ = '+';
} else {
*d++ = '%';
*d++ = "0123456789ABCDEF"[((*c >> 4) & 0xf)];
*d++ = "0123456789ABCDEF"[(*c & 0xf)];
*pos++ = '%';
*pos++ = "0123456789ABCDEF"[(*c >> 4) & 0xf];
*pos++ = "0123456789ABCDEF"[*c & 0xf];
}
} else {
/* unreserved characters: [a-zA-Z0-9-._] */
*d++ = *c;
*pos++ = *c;
}
}
*d++ = '\0';
*pos = '\0';
new_len = pos - escaped;
tmpres = malloc(d - escaped + toskip);
if (!tmpres) {
free(escaped);
return NSERROR_NOMEM;
if (new_len != len) {
/* Shrink wrap the allocation around the escaped string */
char *tmp = realloc(escaped, new_len + 1);
if (tmp != NULL) {
escaped = tmp;
}
}
memcpy(tmpres, unescaped, toskip);
memcpy(tmpres + toskip, escaped, d - escaped);
*result = tmpres;
free(escaped);
*result = escaped;
return NSERROR_OK;
}

View File

@ -32,13 +32,12 @@
* Escape a string suitable for inclusion in an URL.
*
* \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 NSERROR_OK on success
*/
nserror url_escape(const char *unescaped, size_t toskip, bool sptoplus,
nserror url_escape(const char *unescaped, bool sptoplus,
const char *escexceptions, char **result);