curl.h: add CURLE_TOO_LARGE

A new error code to be used when an internal field grows too large, like
when a dynbuf reaches its maximum. Previously it would return
CURLE_OUT_OF_MEMORY for this, which is highly misleading.

Ref: #12268
Closes #12269
This commit is contained in:
Daniel Stenberg 2023-12-18 10:34:17 +01:00
parent b7258e4922
commit f58e493e44
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
13 changed files with 132 additions and 91 deletions

View File

@ -288,6 +288,8 @@ the specific problem.
SSL Client Certificate required. SSL Client Certificate required.
.IP "CURLE_UNRECOVERABLE_POLL (99)" .IP "CURLE_UNRECOVERABLE_POLL (99)"
An internal call to poll() or select() returned error that is not recoverable. An internal call to poll() or select() returned error that is not recoverable.
.IP "CURLE_TOO_LARGE (100)"
A value or data field grew larger than allowed.
.SH "CURLMcode" .SH "CURLMcode"
This is the generic return code used by functions in the libcurl multi This is the generic return code used by functions in the libcurl multi
interface. Also consider \fIcurl_multi_strerror(3)\fP. interface. Also consider \fIcurl_multi_strerror(3)\fP.
@ -410,6 +412,8 @@ The URL contained an invalid number of slashes.
The user part of the URL contained bad or invalid characters. The user part of the URL contained bad or invalid characters.
.IP "CURLUE_LACKS_IDN (30)" .IP "CURLUE_LACKS_IDN (30)"
libcurl lacks IDN support. libcurl lacks IDN support.
.IP "CURLUE_TOO_LARGE (31)"
A value or data field is larger than allowed.
.SH "CURLHcode" .SH "CURLHcode"
The header interface returns a \fICURLHcode\fP to indicate when an error has The header interface returns a \fICURLHcode\fP to indicate when an error has
occurred. occurred.

View File

@ -328,6 +328,7 @@ CURLE_TFTP_NOSUCHUSER 7.15.0
CURLE_TFTP_NOTFOUND 7.15.0 CURLE_TFTP_NOTFOUND 7.15.0
CURLE_TFTP_PERM 7.15.0 CURLE_TFTP_PERM 7.15.0
CURLE_TFTP_UNKNOWNID 7.15.0 CURLE_TFTP_UNKNOWNID 7.15.0
CURLE_TOO_LARGE 8.6.0
CURLE_TOO_MANY_REDIRECTS 7.5 CURLE_TOO_MANY_REDIRECTS 7.5
CURLE_UNKNOWN_OPTION 7.21.5 CURLE_UNKNOWN_OPTION 7.21.5
CURLE_UNKNOWN_TELNET_OPTION 7.7 7.21.5 CURLE_UNKNOWN_TELNET_OPTION 7.7 7.21.5
@ -1094,6 +1095,7 @@ CURLUE_NO_USER 7.62.0
CURLUE_NO_ZONEID 7.81.0 CURLUE_NO_ZONEID 7.81.0
CURLUE_OK 7.62.0 CURLUE_OK 7.62.0
CURLUE_OUT_OF_MEMORY 7.62.0 CURLUE_OUT_OF_MEMORY 7.62.0
CURLUE_TOO_LARGE 8.6.0
CURLUE_UNKNOWN_PART 7.62.0 CURLUE_UNKNOWN_PART 7.62.0
CURLUE_UNSUPPORTED_SCHEME 7.62.0 CURLUE_UNSUPPORTED_SCHEME 7.62.0
CURLUE_URLDECODE 7.62.0 CURLUE_URLDECODE 7.62.0

View File

@ -631,6 +631,7 @@ typedef enum {
CURLE_PROXY, /* 97 - proxy handshake error */ CURLE_PROXY, /* 97 - proxy handshake error */
CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */ CURLE_SSL_CLIENTCERT, /* 98 - client-side certificate required */
CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */ CURLE_UNRECOVERABLE_POLL, /* 99 - poll/select returned fatal error */
CURLE_TOO_LARGE, /* 100 - a value/data met its maximum */
CURL_LAST /* never use! */ CURL_LAST /* never use! */
} CURLcode; } CURLcode;

View File

@ -63,6 +63,7 @@ typedef enum {
CURLUE_BAD_SLASHES, /* 28 */ CURLUE_BAD_SLASHES, /* 28 */
CURLUE_BAD_USER, /* 29 */ CURLUE_BAD_USER, /* 29 */
CURLUE_LACKS_IDN, /* 30 */ CURLUE_LACKS_IDN, /* 30 */
CURLUE_TOO_LARGE, /* 31 */
CURLUE_LAST CURLUE_LAST
} CURLUcode; } CURLUcode;

View File

@ -148,7 +148,7 @@ static int hyper_each_header(void *userdata,
if(name_len + value_len + 2 > CURL_MAX_HTTP_HEADER) { if(name_len + value_len + 2 > CURL_MAX_HTTP_HEADER) {
failf(data, "Too long response header"); failf(data, "Too long response header");
data->state.hresult = CURLE_OUT_OF_MEMORY; data->state.hresult = CURLE_TOO_LARGE;
return HYPER_ITER_BREAK; return HYPER_ITER_BREAK;
} }

View File

@ -31,6 +31,10 @@
#include <curl/mprintf.h> #include <curl/mprintf.h>
#define MERR_OK 0
#define MERR_MEM 1
#define MERR_TOO_LARGE 2
# undef printf # undef printf
# undef fprintf # undef fprintf
# undef msnprintf # undef msnprintf

View File

@ -81,7 +81,7 @@ static CURLcode dyn_nappend(struct dynbuf *s,
if(fit > s->toobig) { if(fit > s->toobig) {
Curl_dyn_free(s); Curl_dyn_free(s);
return CURLE_OUT_OF_MEMORY; return CURLE_TOO_LARGE;
} }
else if(!a) { else if(!a) {
DEBUGASSERT(!indx); DEBUGASSERT(!indx);
@ -199,6 +199,9 @@ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
if(!rc) if(!rc)
return CURLE_OK; return CURLE_OK;
else if(rc == MERR_TOO_LARGE)
return CURLE_TOO_LARGE;
return CURLE_OUT_OF_MEMORY;
#else #else
char *str; char *str;
#ifdef __clang__ #ifdef __clang__
@ -217,8 +220,8 @@ CURLcode Curl_dyn_vaddf(struct dynbuf *s, const char *fmt, va_list ap)
} }
/* If we failed, we cleanup the whole buffer and return error */ /* If we failed, we cleanup the whole buffer and return error */
Curl_dyn_free(s); Curl_dyn_free(s);
return CURLE_OK;
#endif #endif
return CURLE_OUT_OF_MEMORY;
} }
/* /*

View File

@ -3179,7 +3179,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
) { ) {
result = Curl_http2_switch(data, conn, FIRSTSOCKET); result = Curl_http2_switch(data, conn, FIRSTSOCKET);
if(result) if(result)
return result; goto fail;
} }
else else
#endif #endif
@ -3194,7 +3194,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
DEBUGF(infof(data, "HTTP/2 over clean TCP")); DEBUGF(infof(data, "HTTP/2 over clean TCP"));
result = Curl_http2_switch(data, conn, FIRSTSOCKET); result = Curl_http2_switch(data, conn, FIRSTSOCKET);
if(result) if(result)
return result; goto fail;
} }
break; break;
} }
@ -3204,11 +3204,11 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
result = Curl_http_host(data, conn); result = Curl_http_host(data, conn);
if(result) if(result)
return result; goto fail;
result = Curl_http_useragent(data); result = Curl_http_useragent(data);
if(result) if(result)
return result; goto fail;
Curl_http_method(data, conn, &request, &httpreq); Curl_http_method(data, conn, &request, &httpreq);
@ -3224,7 +3224,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
(pq ? pq : data->state.up.path), FALSE); (pq ? pq : data->state.up.path), FALSE);
free(pq); free(pq);
if(result) if(result)
return result; goto fail;
} }
Curl_safefree(data->state.aptr.ref); Curl_safefree(data->state.aptr.ref);
@ -3249,23 +3249,23 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
/* we only consider transfer-encoding magic if libz support is built-in */ /* we only consider transfer-encoding magic if libz support is built-in */
result = Curl_transferencode(data); result = Curl_transferencode(data);
if(result) if(result)
return result; goto fail;
#endif #endif
result = Curl_http_body(data, conn, httpreq, &te); result = Curl_http_body(data, conn, httpreq, &te);
if(result) if(result)
return result; goto fail;
p_accept = Curl_checkheaders(data, p_accept = Curl_checkheaders(data,
STRCONST("Accept"))?NULL:"Accept: */*\r\n"; STRCONST("Accept"))?NULL:"Accept: */*\r\n";
result = Curl_http_resume(data, conn, httpreq); result = Curl_http_resume(data, conn, httpreq);
if(result) if(result)
return result; goto fail;
result = Curl_http_range(data, httpreq); result = Curl_http_range(data, httpreq);
if(result) if(result)
return result; goto fail;
httpstring = get_http_string(data, conn); httpstring = get_http_string(data, conn);
@ -3283,7 +3283,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
result = Curl_http_target(data, conn, &req); result = Curl_http_target(data, conn, &req);
if(result) { if(result) {
Curl_dyn_free(&req); Curl_dyn_free(&req);
return result; goto fail;
} }
#ifndef CURL_DISABLE_ALTSVC #ifndef CURL_DISABLE_ALTSVC
@ -3354,7 +3354,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
if(result) { if(result) {
Curl_dyn_free(&req); Curl_dyn_free(&req);
return result; goto fail;
} }
if(!(conn->handler->flags&PROTOPT_SSL) && if(!(conn->handler->flags&PROTOPT_SSL) &&
@ -3390,7 +3390,7 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
} }
if(result) { if(result) {
Curl_dyn_free(&req); Curl_dyn_free(&req);
return result; goto fail;
} }
if((http->postsize > -1) && if((http->postsize > -1) &&
@ -3426,6 +3426,9 @@ CURLcode Curl_http(struct Curl_easy *data, bool *done)
but is disabled here again to avoid that the chunked encoded version is but is disabled here again to avoid that the chunked encoded version is
actually used when sending the request body over h2 */ actually used when sending the request body over h2 */
data->req.upload_chunky = FALSE; data->req.upload_chunky = FALSE;
fail:
if(CURLE_TOO_LARGE == result)
failf(data, "HTTP request too large");
return result; return result;
} }

View File

@ -39,6 +39,7 @@
#include "curl_setup.h" #include "curl_setup.h"
#include "dynbuf.h" #include "dynbuf.h"
#include "curl_printf.h"
#include <curl/mprintf.h> #include <curl/mprintf.h>
#include "curl_memory.h" #include "curl_memory.h"
@ -169,8 +170,7 @@ struct nsprintf {
struct asprintf { struct asprintf {
struct dynbuf *b; struct dynbuf *b;
bool fail; /* if an alloc has failed and thus the output is not the complete char merr;
data */
}; };
static long dprintf_DollarString(char *input, char **end) static long dprintf_DollarString(char *input, char **end)
@ -1062,25 +1062,27 @@ static int alloc_addbyter(int output, FILE *data)
{ {
struct asprintf *infop = (struct asprintf *)data; struct asprintf *infop = (struct asprintf *)data;
unsigned char outc = (unsigned char)output; unsigned char outc = (unsigned char)output;
CURLcode result;
if(Curl_dyn_addn(infop->b, &outc, 1)) { result = Curl_dyn_addn(infop->b, &outc, 1);
infop->fail = 1; if(result) {
infop->merr = result == CURLE_TOO_LARGE ? MERR_TOO_LARGE : MERR_MEM;
return -1; /* fail */ return -1; /* fail */
} }
return outc; /* fputc() returns like this on success */ return outc; /* fputc() returns like this on success */
} }
/* appends the formatted string, returns 0 on success, 1 on error */ /* appends the formatted string, returns MERR error code */
int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save) int Curl_dyn_vprintf(struct dynbuf *dyn, const char *format, va_list ap_save)
{ {
struct asprintf info; struct asprintf info;
info.b = dyn; info.b = dyn;
info.fail = 0; info.merr = MERR_OK;
(void)dprintf_formatf(&info, alloc_addbyter, format, ap_save); (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save);
if(info.fail) { if(info.merr) {
Curl_dyn_free(info.b); Curl_dyn_free(info.b);
return 1; return info.merr;
} }
return 0; return 0;
} }
@ -1091,10 +1093,10 @@ char *curl_mvaprintf(const char *format, va_list ap_save)
struct dynbuf dyn; struct dynbuf dyn;
info.b = &dyn; info.b = &dyn;
Curl_dyn_init(info.b, DYN_APRINTF); Curl_dyn_init(info.b, DYN_APRINTF);
info.fail = 0; info.merr = MERR_OK;
(void)dprintf_formatf(&info, alloc_addbyter, format, ap_save); (void)dprintf_formatf(&info, alloc_addbyter, format, ap_save);
if(info.fail) { if(info.merr) {
Curl_dyn_free(info.b); Curl_dyn_free(info.b);
return NULL; return NULL;
} }

View File

@ -319,6 +319,9 @@ curl_easy_strerror(CURLcode error)
case CURLE_UNRECOVERABLE_POLL: case CURLE_UNRECOVERABLE_POLL:
return "Unrecoverable error in select/poll"; return "Unrecoverable error in select/poll";
case CURLE_TOO_LARGE:
return "A value or data field grew larger than allowed";
/* error codes not used by current libcurl */ /* error codes not used by current libcurl */
case CURLE_OBSOLETE20: case CURLE_OBSOLETE20:
case CURLE_OBSOLETE24: case CURLE_OBSOLETE24:
@ -553,6 +556,9 @@ curl_url_strerror(CURLUcode error)
case CURLUE_LACKS_IDN: case CURLUE_LACKS_IDN:
return "libcurl lacks IDN support"; return "libcurl lacks IDN support";
case CURLUE_TOO_LARGE:
return "A value or data field is larger than allowed";
case CURLUE_LAST: case CURLUE_LAST:
break; break;
} }

View File

@ -126,6 +126,9 @@ static const char *find_host_sep(const char *url)
return sep < query ? sep : query; 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. * 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; bool left = !query;
const unsigned char *iptr; const unsigned char *iptr;
const unsigned char *host_sep = (const unsigned char *) url; const unsigned char *host_sep = (const unsigned char *) url;
CURLcode result;
if(!relative) if(!relative)
host_sep = (const unsigned char *) find_host_sep(url); 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--) { len; iptr++, len--) {
if(iptr < host_sep) { if(iptr < host_sep) {
if(Curl_dyn_addn(o, iptr, 1)) result = Curl_dyn_addn(o, iptr, 1);
return CURLUE_OUT_OF_MEMORY; if(result)
return cc2cu(result);
continue; continue;
} }
if(*iptr == ' ') { if(*iptr == ' ') {
if(left) { if(left)
if(Curl_dyn_addn(o, "%20", 3)) result = Curl_dyn_addn(o, "%20", 3);
return CURLUE_OUT_OF_MEMORY; else
} result = Curl_dyn_addn(o, "+", 1);
else { if(result)
if(Curl_dyn_addn(o, "+", 1)) return cc2cu(result);
return CURLUE_OUT_OF_MEMORY;
}
continue; continue;
} }
@ -178,13 +181,12 @@ static CURLUcode urlencode_str(struct dynbuf *o, const char *url,
char out[3]={'%'}; char out[3]={'%'};
out[1] = hexdigits[*iptr>>4]; out[1] = hexdigits[*iptr>>4];
out[2] = hexdigits[*iptr & 0xf]; out[2] = hexdigits[*iptr & 0xf];
if(Curl_dyn_addn(o, out, 3)) result = Curl_dyn_addn(o, out, 3);
return CURLUE_OUT_OF_MEMORY;
}
else {
if(Curl_dyn_addn(o, iptr, 1))
return CURLUE_OUT_OF_MEMORY;
} }
else
result = Curl_dyn_addn(o, iptr, 1);
if(result)
return cc2cu(result);
} }
return CURLUE_OK; 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. * 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 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; char *pathsep;
bool host_changed = FALSE; bool host_changed = FALSE;
const char *useurl = relurl; const char *useurl = relurl;
CURLcode result = CURLE_OK;
CURLUcode uc;
*newurl = NULL;
/* protsep points to the start of the host name */ /* protsep points to the start of the host name */
protsep = strstr(base, "//"); protsep = strstr(base, "//");
@ -360,21 +365,27 @@ static char *concat_url(char *base, const char *relurl)
Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&newest, CURL_MAX_INPUT_LENGTH);
/* copy over the root url part */ /* copy over the root url part */
if(Curl_dyn_add(&newest, base)) result = Curl_dyn_add(&newest, base);
return NULL; if(result)
return result;
/* check if we need to append a slash */ /* check if we need to append a slash */
if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0])) if(('/' == useurl[0]) || (protsep && !*protsep) || ('?' == useurl[0]))
; ;
else { else {
if(Curl_dyn_addn(&newest, "/", 1)) result = Curl_dyn_addn(&newest, "/", 1);
return NULL; if(result)
return result;
} }
/* then append the new piece on the right side */ /* 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 */ /* scan for byte values <= 31, 127 and sometimes space */
@ -775,7 +786,7 @@ static CURLUcode urldecode_host(struct dynbuf *host)
result = Curl_dyn_addn(host, decoded, dlen); result = Curl_dyn_addn(host, decoded, dlen);
free(decoded); free(decoded);
if(result) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
} }
return CURLUE_OK; return CURLUE_OK;
@ -788,22 +799,24 @@ static CURLUcode parse_authority(struct Curl_URL *u,
bool has_scheme) bool has_scheme)
{ {
size_t offset; size_t offset;
CURLUcode result; CURLUcode uc;
CURLcode result;
/* /*
* Parse the login details and strip them out of the host name. * Parse the login details and strip them out of the host name.
*/ */
result = parse_hostname_login(u, auth, authlen, flags, &offset); uc = parse_hostname_login(u, auth, authlen, flags, &offset);
if(result) if(uc)
goto out; goto out;
if(Curl_dyn_addn(host, auth + offset, authlen - offset)) { result = Curl_dyn_addn(host, auth + offset, authlen - offset);
result = CURLUE_OUT_OF_MEMORY; if(result) {
uc = cc2cu(result);
goto out; goto out;
} }
result = Curl_parse_port(u, host, has_scheme); uc = Curl_parse_port(u, host, has_scheme);
if(result) if(uc)
goto out; goto out;
if(!Curl_dyn_len(host)) if(!Curl_dyn_len(host))
@ -813,24 +826,24 @@ static CURLUcode parse_authority(struct Curl_URL *u,
case HOST_IPV4: case HOST_IPV4:
break; break;
case HOST_IPV6: 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; break;
case HOST_NAME: case HOST_NAME:
result = urldecode_host(host); uc = urldecode_host(host);
if(!result) if(!uc)
result = hostname_check(u, Curl_dyn_ptr(host), Curl_dyn_len(host)); uc = hostname_check(u, Curl_dyn_ptr(host), Curl_dyn_len(host));
break; break;
case HOST_ERROR: case HOST_ERROR:
result = CURLUE_OUT_OF_MEMORY; uc = CURLUE_OUT_OF_MEMORY;
break; break;
case HOST_BAD: case HOST_BAD:
default: default:
result = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */ uc = CURLUE_BAD_HOSTNAME; /* Bad IPv4 address even */
break; break;
} }
out: out:
return result; return uc;
} }
CURLUcode Curl_url_set_authority(CURLU *u, const char *authority, CURLUcode Curl_url_set_authority(CURLU *u, const char *authority,
@ -1079,8 +1092,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
len = path - ptr; len = path - ptr;
if(len) { if(len) {
if(Curl_dyn_addn(&host, ptr, len)) { CURLcode code = Curl_dyn_addn(&host, ptr, len);
result = CURLUE_OUT_OF_MEMORY; if(code) {
result = cc2cu(code);
goto fail; goto fail;
} }
uncpath = TRUE; uncpath = TRUE;
@ -1233,10 +1247,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
if(flags & CURLU_URLENCODE) { if(flags & CURLU_URLENCODE) {
struct dynbuf enc; struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
if(urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, FALSE)) { result = urlencode_str(&enc, fragment + 1, fraglen - 1, TRUE, FALSE);
result = CURLUE_OUT_OF_MEMORY; if(result)
goto fail; goto fail;
}
u->fragment = Curl_dyn_ptr(&enc); u->fragment = Curl_dyn_ptr(&enc);
} }
else { else {
@ -1262,10 +1275,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
struct dynbuf enc; struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
/* skip the leading question mark */ /* skip the leading question mark */
if(urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE)) { result = urlencode_str(&enc, query + 1, qlen - 1, TRUE, TRUE);
result = CURLUE_OUT_OF_MEMORY; if(result)
goto fail; goto fail;
}
u->query = Curl_dyn_ptr(&enc); u->query = Curl_dyn_ptr(&enc);
} }
else { else {
@ -1289,10 +1301,9 @@ static CURLUcode parseurl(const char *url, CURLU *u, unsigned int flags)
if(pathlen && (flags & CURLU_URLENCODE)) { if(pathlen && (flags & CURLU_URLENCODE)) {
struct dynbuf enc; struct dynbuf enc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
if(urlencode_str(&enc, path, pathlen, TRUE, FALSE)) { result = urlencode_str(&enc, path, pathlen, TRUE, FALSE);
result = CURLUE_OUT_OF_MEMORY; if(result)
goto fail; goto fail;
}
pathlen = Curl_dyn_len(&enc); pathlen = Curl_dyn_len(&enc);
path = u->path = Curl_dyn_ptr(&enc); path = u->path = Curl_dyn_ptr(&enc);
} }
@ -1628,10 +1639,11 @@ CURLUcode curl_url_get(const CURLU *u, CURLUPart what,
} }
if(urlencode) { if(urlencode) {
struct dynbuf enc; struct dynbuf enc;
CURLUcode uc;
Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH); Curl_dyn_init(&enc, CURL_MAX_INPUT_LENGTH);
if(urlencode_str(&enc, *part, partlen, TRUE, uc = urlencode_str(&enc, *part, partlen, TRUE, what == CURLUPART_QUERY);
what == CURLUPART_QUERY)) if(uc)
return CURLUE_OUT_OF_MEMORY; return uc;
free(*part); free(*part);
*part = Curl_dyn_ptr(&enc); *part = Curl_dyn_ptr(&enc);
} }
@ -1816,7 +1828,8 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
* If the existing contents is enough for a URL, allow a relative URL to * If the existing contents is enough for a URL, allow a relative URL to
* replace it. * replace it.
*/ */
CURLUcode result; CURLcode result;
CURLUcode uc;
char *oldurl; char *oldurl;
char *redired_url; char *redired_url;
@ -1836,14 +1849,14 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
/* apply the relative part to create a new URL /* apply the relative part to create a new URL
* and replace the existing one with it. */ * and replace the existing one with it. */
redired_url = concat_url(oldurl, part); result = concat_url(oldurl, part, &redired_url);
free(oldurl); free(oldurl);
if(!redired_url) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
result = parseurl_and_replace(redired_url, u, flags); uc = parseurl_and_replace(redired_url, u, flags);
free(redired_url); free(redired_url);
return result; return uc;
} }
default: default:
return CURLUE_UNKNOWN_PART; return CURLUE_UNKNOWN_PART;
@ -1857,7 +1870,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
if(leadingslash && (part[0] != '/')) { if(leadingslash && (part[0] != '/')) {
CURLcode result = Curl_dyn_addn(&enc, "/", 1); CURLcode result = Curl_dyn_addn(&enc, "/", 1);
if(result) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
} }
if(urlencode) { if(urlencode) {
const unsigned char *i; const unsigned char *i;
@ -1877,7 +1890,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
equalsencode = FALSE; equalsencode = FALSE;
result = Curl_dyn_addn(&enc, i, 1); result = Curl_dyn_addn(&enc, i, 1);
if(result) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
} }
else { else {
char out[3]={'%'}; char out[3]={'%'};
@ -1885,7 +1898,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
out[2] = hexdigits[*i & 0xf]; out[2] = hexdigits[*i & 0xf];
result = Curl_dyn_addn(&enc, out, 3); result = Curl_dyn_addn(&enc, out, 3);
if(result) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
} }
} }
} }
@ -1893,7 +1906,7 @@ CURLUcode curl_url_set(CURLU *u, CURLUPart what,
char *p; char *p;
CURLcode result = Curl_dyn_add(&enc, part); CURLcode result = Curl_dyn_add(&enc, part);
if(result) if(result)
return CURLUE_OUT_OF_MEMORY; return cc2cu(result);
p = Curl_dyn_ptr(&enc); p = Curl_dyn_ptr(&enc);
while(*p) { while(*p) {
/* make sure percent encoded are lower case */ /* make sure percent encoded are lower case */

View File

@ -47,9 +47,9 @@ User-Agent: curl/%VERSION
Accept: */* Accept: */*
</protocol> </protocol>
# 27 == CURLE_OUT_OF_MEMORY # 100 == CURLE_TOO_LARGE
<errorcode> <errorcode>
27 100
</errorcode> </errorcode>
</verify> </verify>
</testcase> </testcase>

View File

@ -132,7 +132,8 @@ e96: QUIC connection error
e97: proxy handshake error e97: proxy handshake error
e98: SSL Client Certificate required e98: SSL Client Certificate required
e99: Unrecoverable error in select/poll e99: Unrecoverable error in select/poll
e100: Unknown error e100: A value or data field grew larger than allowed
e101: Unknown error
m-1: Please call curl_multi_perform() soon m-1: Please call curl_multi_perform() soon
m0: No error m0: No error
m1: Invalid multi handle m1: Invalid multi handle
@ -186,7 +187,8 @@ u27: Bad scheme
u28: Unsupported number of slashes following scheme u28: Unsupported number of slashes following scheme
u29: Bad user u29: Bad user
u30: libcurl lacks IDN support u30: libcurl lacks IDN support
u31: CURLUcode unknown u31: A value or data field is larger than allowed
u32: CURLUcode unknown
</stdout> </stdout>
</verify> </verify>