diff options
author | Michael Drake <tlsa@netsurf-browser.org> | 2016-07-24 21:00:29 +0100 |
---|---|---|
committer | Michael Drake <tlsa@netsurf-browser.org> | 2016-07-25 09:04:35 +0100 |
commit | a122b94efde125202388d135e36eb86e6d25d093 (patch) | |
tree | 73e9d34dbc6c7443c727b8d85ba2c1127e4ed1c3 /utils/url.c | |
parent | 7bff70e7466dd80603922ba0dfdad1725cce41a6 (diff) | |
download | netsurf-a122b94efde125202388d135e36eb86e6d25d093.tar.gz netsurf-a122b94efde125202388d135e36eb86e6d25d093.tar.bz2 |
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.
Diffstat (limited to 'utils/url.c')
-rw-r--r-- | utils/url.c | 65 |
1 files changed, 31 insertions, 34 deletions
diff --git a/utils/url.c b/utils/url.c index d1e9ce2a7..861a62bdc 100644 --- a/utils/url.c +++ b/utils/url.c @@ -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; } |