diff options
Diffstat (limited to 'libs/libcurl/src/urlapi.c')
-rw-r--r-- | libs/libcurl/src/urlapi.c | 169 |
1 files changed, 95 insertions, 74 deletions
diff --git a/libs/libcurl/src/urlapi.c b/libs/libcurl/src/urlapi.c index 1a94e7f4cf..70b63983f7 100644 --- a/libs/libcurl/src/urlapi.c +++ b/libs/libcurl/src/urlapi.c @@ -126,6 +126,9 @@ static const char *find_host_sep(const char *url) return sep < query ? sep : query;
}
+/* convert CURLcode to CURLUcode */
+#define cc2cu(x) ((x) == CURLE_TOO_LARGE ? CURLUE_TOO_LARGE : \
+ CURLUE_OUT_OF_MEMORY)
/*
* Decide whether a character in a URL must be escaped.
*/
@@ -146,6 +149,7 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, bool left = !query;
const unsigned char *iptr;
const unsigned char *host_sep = (const unsigned char *) url;
+ CURLcode result;
if(!relative)
host_sep = (const unsigned char *) find_host_sep(url);
@@ -154,20 +158,19 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, len; iptr++, len--) {
if(iptr < host_sep) {
- if(Curl_dyn_addn(o, iptr, 1))
- return CURLUE_OUT_OF_MEMORY;
+ result = Curl_dyn_addn(o, iptr, 1);
+ if(result)
+ return cc2cu(result);
continue;
}
if(*iptr == ' ') {
- if(left) {
- if(Curl_dyn_addn(o, "%20", 3))
- return CURLUE_OUT_OF_MEMORY;
- }
- else {
- if(Curl_dyn_addn(o, "+", 1))
- return CURLUE_OUT_OF_MEMORY;
- }
+ if(left)
+ result = Curl_dyn_addn(o, "%20", 3);
+ else
+ result = Curl_dyn_addn(o, "+", 1);
+ if(result)
+ return cc2cu(result);
continue;
}
@@ -178,13 +181,12 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url, char out[3]={'%'};
out[1] = hexdigits[*iptr>>4];
out[2] = hexdigits[*iptr & 0xf];
- if(Curl_dyn_addn(o, out, 3))
- return CURLUE_OUT_OF_MEMORY;
- }
- else {
- if(Curl_dyn_addn(o, iptr, 1))
- return CURLUE_OUT_OF_MEMORY;
+ result = Curl_dyn_addn(o, out, 3);
}
+ else
+ result = Curl_dyn_addn(o, iptr, 1);
+ if(result)
+ return cc2cu(result);
}
return CURLUE_OK;
@@ -248,7 +250,7 @@ size_t Curl_is_absolute_url(const char *url, char *buf, size_t buflen, *
* Note that this function destroys the 'base' string.
*/
-static char *concat_url(char *base, const char *relurl)
+static CURLcode concat_url(char *base, const char *relurl, char **newurl)
{
/***
TRY to append this new path to the old URL
@@ -260,6 +262,9 @@ static char *concat_url(char *base, const char *relurl) char *pathsep;
bool host_changed = FALSE;
const char *useurl = relurl;
+ CURLcode result = CURLE_OK;
+ CURLUcode uc;
+ *newurl = NULL;
/* protsep points to the start of the host name */
protsep = strstr(base, "//");
@@ -360,21 +365,27 @@ static char *concat_url(char *base, const char *relurl) Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH);
/* copy over the root url part */
- if(Curl_dyn_add(&newest, base))
- return NULL;
+ result = Curl_dyn_add(&newest, base);
+ if(result)
+ return result;
/* check if we need to append a slash */
if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
;
else {
- if(Curl_dyn_addn(&newest, "/", 1))
- return NULL;
+ result = Curl_dyn_addn(&newest, "/", 1);
+ if(result)
+ return result;
}
/* then append the new piece on the right side */
- urlencode_str(&newest, useurl, strlen(useurl), !host_changed, FALSE);
+ uc = urlencode_str(&newest, useurl, strlen(useurl), !host_changed,
+ FALSE);
+ if(uc)
+ return (uc == CURLUE_TOO_LARGE) ? CURLE_TOO_LARGE : CURLE_OUT_OF_MEMORY;
- return Curl_dyn_ptr(&newest);
+ *newurl = Curl_dyn_ptr(&newest);
+ return CURLE_OK;
}
/* scan for byte values <= 31, 127 and sometimes space */
@@ -712,24 +723,30 @@ static int ipv4_normalize(struct dynbuf *host) Curl_dyn_reset(host);
result = Curl_dyn_addf(host, "%u.%u.%u.%u",
- parts[0] >> 24, (parts[0] >> 16) & 0xff,
- (parts[0] >> 8) & 0xff, parts[0] & 0xff);
+ (unsigned int)(parts[0] >> 24),
+ (unsigned int)((parts[0] >> 16) & 0xff),
+ (unsigned int)((parts[0] >> 8) & 0xff),
+ (unsigned int)(parts[0] & 0xff));
break;
case 1: /* a.b -- 8.24 bits */
if((parts[0] > 0xff) || (parts[1] > 0xffffff))
return HOST_NAME;
Curl_dyn_reset(host);
result = Curl_dyn_addf(host, "%u.%u.%u.%u",
- parts[0], (parts[1] >> 16) & 0xff,
- (parts[1] >> 8) & 0xff, parts[1] & 0xff);
+ (unsigned int)(parts[0]),
+ (unsigned int)((parts[1] >> 16) & 0xff),
+ (unsigned int)((parts[1] >> 8) & 0xff),
+ (unsigned int)(parts[1] & 0xff));
break;
case 2: /* a.b.c -- 8.8.16 bits */
if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xffff))
return HOST_NAME;
Curl_dyn_reset(host);
result = Curl_dyn_addf(host, "%u.%u.%u.%u",
- parts[0], parts[1], (parts[2] >> 8) & 0xff,
- parts[2] & 0xff);
+ (unsigned int)(parts[0]),
+ (unsigned int)(parts[1]),
+ (unsigned int)((parts[2] >> 8) & 0xff),
+ (unsigned int)(parts[2] & 0xff));
break;
case 3: /* a.b.c.d -- 8.8.8.8 bits */
if((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff) ||
@@ -737,7 +754,10 @@ static int ipv4_normalize(struct dynbuf *host) return HOST_NAME;
Curl_dyn_reset(host);
result = Curl_dyn_addf(host, "%u.%u.%u.%u",
- parts[0], parts[1], parts[2], parts[3]);
+ (unsigned int)(parts[0]),
+ (unsigned int)(parts[1]),
+ (unsigned int)(parts[2]),
+ (unsigned int)(parts[3]));
break;
}
if(result)
@@ -766,7 +786,7 @@ static CURLUcode urldecode_host(struct dynbuf *host) result = Curl_dyn_addn(host, decoded, dlen);
free(decoded);
if(result)
- return CURLUE_OUT_OF_MEMORY;
+ return cc2cu(result);
}
return CURLUE_OK;
@@ -779,22 +799,24 @@ static CURLUcode parse_authority(struct Curl_URL *u, bool has_scheme)
{
size_t offset;
- CURLUcode result;
+ CURLUcode uc;
+ CURLcode result;
/*
* Parse the login details and strip them out of the host name.
*/
- result = parse_hostname_login(u, auth, authlen, flags, &offset);
- if(result)
+ uc = parse_hostname_login(u, auth, authlen, flags, &offset);
+ if(uc)
goto out;
- if(Curl_dyn_addn(host, auth + offset, authlen - offset)) {
- result = CURLUE_OUT_OF_MEMORY;
+ result = Curl_dyn_addn(host, auth + offset, authlen - offset);
+ if(result) {
+ uc = cc2cu(result);
goto out;
}
- result = Curl_parse_port(u, host, has_scheme);
- if(result)
+ uc = Curl_parse_port(u, host, has_scheme);
+ if(uc)
goto out;
if(!Curl_dyn_len(host))
@@ -804,24 +826,24 @@ static CURLUcode parse_authority(struct Curl_URL *u, case HOST_IPV4:
break;
case HOST_IPV6:
- result = ipv6_parse(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
+ uc = ipv6_parse(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
break;
case HOST_NAME:
- result = urldecode_host(host);
- if(!result)
- result = hostname_check(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
+ uc = urldecode_host(host);
+ if(!uc)
+ uc = hostname_check(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
break;
case HOST_ERROR:
- result = CURLUE_OUT_OF_MEMORY;
+ uc = CURLUE_OUT_OF_MEMORY;
break;
case HOST_BAD:
default:
- result = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */
+ uc = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */
break;
}
out:
- return result;
+ return uc;
}
CURLUcode Curl_url_set_authority(CURLU *u, const char *authority,
@@ -1070,8 +1092,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) len = path - ptr;
if(len) {
- if(Curl_dyn_addn(&host, ptr, len)) {
- result = CURLUE_OUT_OF_MEMORY;
+ CURLcode code = Curl_dyn_addn(&host, ptr, len);
+ if(code) {
+ result = cc2cu(code);
goto fail;
}
uncpath = TRUE;
@@ -1224,14 +1247,13 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) if(flags & CURLU_URLENCODE) {
struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
- if(urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, FALSE)) {
- result = CURLUE_OUT_OF_MEMORY;
+ result = urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, FALSE);
+ if(result)
goto fail;
- }
u->fragment = Curl_dyn_ptr(&enc);
}
else {
- u->fragment = Curl_strndup(fragment + 1, fraglen - 1);
+ u->fragment = Curl_memdup0(fragment + 1, fraglen - 1);
if(!u->fragment) {
result = CURLUE_OUT_OF_MEMORY;
goto fail;
@@ -1242,7 +1264,6 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) pathlen -= fraglen;
}
- DEBUGASSERT(pathlen < urllen);
query = memchr(path, '?', pathlen);
if(query) {
size_t qlen = fragment ? (size_t)(fragment - query) :
@@ -1253,14 +1274,13 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
/* skip the leading question mark */
- if(urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE)) {
- result = CURLUE_OUT_OF_MEMORY;
+ result = urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE);
+ if(result)
goto fail;
- }
u->query = Curl_dyn_ptr(&enc);
}
else {
- u->query = Curl_strndup(query + 1, qlen - 1);
+ u->query = Curl_memdup0(query + 1, qlen - 1);
if(!u->query) {
result = CURLUE_OUT_OF_MEMORY;
goto fail;
@@ -1280,10 +1300,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) if(pathlen && (flags & CURLU_URLENCODE)) {
struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
- if(urlencode_str(&enc, path, pathlen, TRUE, FALSE)) {
- result = CURLUE_OUT_OF_MEMORY;
+ result = urlencode_str(&enc, path, pathlen, TRUE, FALSE);
+ if(result)
goto fail;
- }
pathlen = Curl_dyn_len(&enc);
path = u->path = Curl_dyn_ptr(&enc);
}
@@ -1294,7 +1313,7 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags) }
else {
if(!u->path) {
- u->path = Curl_strndup(path, pathlen);
+ u->path = Curl_memdup0(path, pathlen);
if(!u->path) {
result = CURLUE_OUT_OF_MEMORY;
goto fail;
@@ -1592,7 +1611,7 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, if(ptr) {
size_t partlen = strlen(ptr);
size_t i = 0;
- *part = Curl_strndup(ptr, partlen);
+ *part = Curl_memdup0(ptr, partlen);
if(!*part)
return CURLUE_OUT_OF_MEMORY;
if(plusdecode) {
@@ -1619,10 +1638,11 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what, }
if(urlencode) {
struct dynbuf enc;
+ CURLUcode uc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
- if(urlencode_str(&enc, *part, partlen, TRUE,
- what == CURLUPART_QUERY))
- return CURLUE_OUT_OF_MEMORY;
+ uc = urlencode_str(&enc, *part, partlen, TRUE, what == CURLUPART_QUERY);
+ if(uc)
+ return uc;
free(*part);
*part = Curl_dyn_ptr(&enc);
}
@@ -1807,7 +1827,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, * If the existing contents is enough for a URL, allow a relative URL to
* replace it.
*/
- CURLUcode result;
+ CURLcode result;
+ CURLUcode uc;
char *oldurl;
char *redired_url;
@@ -1827,14 +1848,14 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, /* apply the relative part to create a new URL
* and replace the existing one with it. */
- redired_url = concat_url(oldurl, part);
+ result = concat_url(oldurl, part, &redired_url);
free(oldurl);
- if(!redired_url)
- return CURLUE_OUT_OF_MEMORY;
+ if(result)
+ return cc2cu(result);
- result = parseurl_and_replace(redired_url, u, flags);
+ uc = parseurl_and_replace(redired_url, u, flags);
free(redired_url);
- return result;
+ return uc;
}
default:
return CURLUE_UNKNOWN_PART;
@@ -1848,7 +1869,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, if(leadingslash && (part[0] != '/')) {
CURLcode result = Curl_dyn_addn(&enc, "/", 1);
if(result)
- return CURLUE_OUT_OF_MEMORY;
+ return cc2cu(result);
}
if(urlencode) {
const unsigned char *i;
@@ -1868,7 +1889,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, equalsencode = FALSE;
result = Curl_dyn_addn(&enc, i, 1);
if(result)
- return CURLUE_OUT_OF_MEMORY;
+ return cc2cu(result);
}
else {
char out[3]={'%'};
@@ -1876,7 +1897,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, out[2] = hexdigits[*i & 0xf];
result = Curl_dyn_addn(&enc, out, 3);
if(result)
- return CURLUE_OUT_OF_MEMORY;
+ return cc2cu(result);
}
}
}
@@ -1884,7 +1905,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what, char *p;
CURLcode result = Curl_dyn_add(&enc, part);
if(result)
- return CURLUE_OUT_OF_MEMORY;
+ return cc2cu(result);
p = Curl_dyn_ptr(&enc);
while(*p) {
/* make sure percent encoded are lower case */
|