curl tool: OOM handling fixes

This commit is contained in:
Yang Tse
2011-10-05 15:06:26 +02:00
parent fd87d9d2b9
commit 5bf0d74120
6 changed files with 71 additions and 37 deletions

View File

@@ -613,7 +613,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* there was no free node, create one! */ /* there was no free node, create one! */
url = new_getout(config); url = new_getout(config);
if(url) { if(!url)
return PARAM_NO_MEM;
else {
/* fill in the URL */ /* fill in the URL */
GetStr(&url->url, nextarg); GetStr(&url->url, nextarg);
url->flags |= GETOUT_URL; url->flags |= GETOUT_URL;
@@ -941,6 +943,8 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* no data from the file, point to a zero byte string to make this /* no data from the file, point to a zero byte string to make this
get sent as a POST anyway */ get sent as a POST anyway */
postdata = strdup(""); postdata = strdup("");
if(!postdata)
return PARAM_NO_MEM;
size = 0; size = 0;
} }
else { else {
@@ -1005,6 +1009,8 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* no data from the file, point to a zero byte string to make this /* no data from the file, point to a zero byte string to make this
get sent as a POST anyway */ get sent as a POST anyway */
postdata = strdup(""); postdata = strdup("");
if(!postdata)
return PARAM_NO_MEM;
} }
} }
else { else {
@@ -1311,7 +1317,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* there was no free node, create one! */ /* there was no free node, create one! */
url = new_getout(config); url = new_getout(config);
if(url) { if(!url)
return PARAM_NO_MEM;
else {
/* fill in the outfile */ /* fill in the outfile */
if('o' == letter) { if('o' == letter) {
GetStr(&url->outfile, nextarg); GetStr(&url->outfile, nextarg);
@@ -1379,6 +1387,8 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
snprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off); snprintf(buffer, sizeof(buffer), "%" CURL_FORMAT_CURL_OFF_T "-", off);
Curl_safefree(config->range); Curl_safefree(config->range);
config->range = strdup(buffer); config->range = strdup(buffer);
if(!config->range)
return PARAM_NO_MEM;
} }
{ {
/* byte range requested */ /* byte range requested */
@@ -1440,7 +1450,9 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* there was no free node, create one! */ /* there was no free node, create one! */
url = new_getout(config); url = new_getout(config);
if(url) { if(!url)
return PARAM_NO_MEM;
else {
url->flags |= GETOUT_UPLOAD; /* mark -T used */ url->flags |= GETOUT_UPLOAD; /* mark -T used */
if(!*nextarg) if(!*nextarg)
url->flags |= GETOUT_NOUPLOAD; url->flags |= GETOUT_NOUPLOAD;
@@ -1455,19 +1467,25 @@ ParameterError getparameter(char *flag, /* f or -long-flag */
/* user:password */ /* user:password */
GetStr(&config->userpwd, nextarg); GetStr(&config->userpwd, nextarg);
cleanarg(nextarg); cleanarg(nextarg);
checkpasswd("host", &config->userpwd); err = checkpasswd("host", &config->userpwd);
if(err)
return err;
break; break;
case 'U': case 'U':
/* Proxy user:password */ /* Proxy user:password */
GetStr(&config->proxyuserpwd, nextarg); GetStr(&config->proxyuserpwd, nextarg);
cleanarg(nextarg); cleanarg(nextarg);
checkpasswd("proxy", &config->proxyuserpwd); err = checkpasswd("proxy", &config->proxyuserpwd);
if(err)
return err;
break; break;
case 'v': case 'v':
if(toggle) { if(toggle) {
/* the '%' thing here will cause the trace get sent to stderr */ /* the '%' thing here will cause the trace get sent to stderr */
Curl_safefree(config->trace_dump); Curl_safefree(config->trace_dump);
config->trace_dump = strdup("%"); config->trace_dump = strdup("%");
if(!config->trace_dump)
return PARAM_NO_MEM;
if(config->tracetype && (config->tracetype != TRACE_PLAIN)) if(config->tracetype && (config->tracetype != TRACE_PLAIN))
warnf(config, warnf(config,
"-v, --verbose overrides an earlier trace/verbose option\n"); "-v, --verbose overrides an earlier trace/verbose option\n");

View File

@@ -317,6 +317,11 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
/* Use the postfields data for a http get */ /* Use the postfields data for a http get */
httpgetfields = strdup(config->postfields); httpgetfields = strdup(config->postfields);
Curl_safefree(config->postfields); Curl_safefree(config->postfields);
if(!httpgetfields) {
helpf(config->errors, "out of memory\n");
res = CURLE_OUT_OF_MEMORY;
goto quit_curl;
}
if(SetHTTPrequest(config, if(SetHTTPrequest(config,
(config->no_body?HTTPREQ_HEAD:HTTPREQ_GET), (config->no_body?HTTPREQ_HEAD:HTTPREQ_GET),
&config->httpreq)) { &config->httpreq)) {
@@ -515,7 +520,9 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
if(!outfile) { if(!outfile) {
/* extract the file name from the URL */ /* extract the file name from the URL */
outfile = get_url_file_name(this_url); res = get_url_file_name(&outfile, this_url);
if(res)
goto show_error;
if((!outfile || !*outfile) && !config->content_disposition) { if((!outfile || !*outfile) && !config->content_disposition) {
helpf(config->errors, "Remote file name has no length!\n"); helpf(config->errors, "Remote file name has no length!\n");
res = CURLE_WRITE_ERROR; res = CURLE_WRITE_ERROR;

View File

@@ -152,14 +152,17 @@ char *add_file_name_to_url(CURL *curl, char *url, const char *filename)
} }
/* Extracts the name portion of the URL. /* Extracts the name portion of the URL.
* Returns a heap-allocated string, or NULL if no name part * Returns a pointer to a heap-allocated string or NULL if
* no name part, at location indicated by first argument.
*/ */
char *get_url_file_name(const char *url) CURLcode get_url_file_name(char **filename, const char *url)
{ {
char *fn = NULL; const char *pc;
*filename = NULL;
/* Find and get the remote file name */ /* Find and get the remote file name */
const char *pc = strstr(url, "://"); pc = strstr(url, "://");
if(pc) if(pc)
pc += 3; pc += 3;
else else
@@ -169,9 +172,13 @@ char *get_url_file_name(const char *url)
if(pc) { if(pc) {
/* duplicate the string beyond the slash */ /* duplicate the string beyond the slash */
pc++; pc++;
fn = *pc ? strdup(pc): NULL; if(*pc) {
*filename = strdup(pc);
if(!*filename)
return CURLE_OUT_OF_MEMORY;
} }
return fn; }
return CURLE_OK;
} }
/* /*

View File

@@ -35,7 +35,7 @@ bool stdin_upload(const char *uploadfile);
char *add_file_name_to_url(CURL *curl, char *url, const char *filename); char *add_file_name_to_url(CURL *curl, char *url, const char *filename);
char *get_url_file_name(const char *url); CURLcode get_url_file_name(char **filename, const char *url);
CURLcode main_init(void); CURLcode main_init(void);

View File

@@ -41,12 +41,9 @@
struct getout *new_getout(struct Configurable *config) struct getout *new_getout(struct Configurable *config)
{ {
struct getout *node =malloc(sizeof(struct getout)); struct getout *node = calloc(1, sizeof(struct getout));
struct getout *last = config->url_last; struct getout *last = config->url_last;
if(node) { if(node) {
/* clear the struct */
memset(node, 0, sizeof(struct getout));
/* append this new node last in the list */ /* append this new node last in the list */
if(last) if(last)
last->next = node; last->next = node;
@@ -120,7 +117,10 @@ ParameterError file2memory(char **bufp, size_t *size, FILE *file)
buffer[nused] = '\0'; buffer[nused] = '\0';
/* free trailing slack space, if possible */ /* free trailing slack space, if possible */
if(alloc != nused) { if(alloc != nused) {
if((newbuf = realloc(buffer, nused+1)) != NULL) if((newbuf = realloc(buffer, nused+1)) == NULL) {
Curl_safefree(buffer);
return PARAM_NO_MEM;
}
buffer = newbuf; buffer = newbuf;
} }
/* discard buffer if nothing was read */ /* discard buffer if nothing was read */
@@ -221,6 +221,8 @@ long proto2num(struct Configurable *config, long *val, const char *str)
return 1; return 1;
buffer = strdup(str); /* because strtok corrupts it */ buffer = strdup(str); /* because strtok corrupts it */
if(!buffer)
return 1;
for(token = strtok(buffer, sep); for(token = strtok(buffer, sep);
token; token;
@@ -298,12 +300,13 @@ int str2offset(curl_off_t *val, const char *str)
return 0; return 0;
} }
void checkpasswd(const char *kind, /* for what purpose */ ParameterError checkpasswd(const char *kind, /* for what purpose */
char **userpwd) /* pointer to allocated string */ char **userpwd) /* pointer to allocated string */
{ {
char *ptr; char *ptr;
if(!*userpwd) if(!*userpwd)
return; return PARAM_OK;
ptr = strchr(*userpwd, ':'); ptr = strchr(*userpwd, ':');
if(!ptr) { if(!ptr) {
@@ -327,14 +330,15 @@ void checkpasswd(const char *kind, /* for what purpose */
passptr = realloc(*userpwd, passptr = realloc(*userpwd,
passwdlen + 1 + /* an extra for the colon */ passwdlen + 1 + /* an extra for the colon */
userlen + 1); /* an extra for the zero */ userlen + 1); /* an extra for the zero */
if(!passptr)
return PARAM_NO_MEM;
if(passptr) {
/* append the password separated with a colon */ /* append the password separated with a colon */
passptr[userlen] = ':'; passptr[userlen] = ':';
memcpy(&passptr[userlen+1], passwd, passwdlen+1); memcpy(&passptr[userlen+1], passwd, passwdlen+1);
*userpwd = passptr; *userpwd = passptr;
} }
} return PARAM_OK;
} }
ParameterError add2list(struct curl_slist **list, const char *ptr) ParameterError add2list(struct curl_slist **list, const char *ptr)

View File

@@ -37,7 +37,7 @@ long proto2num(struct Configurable *config, long *val, const char *str);
int str2offset(curl_off_t *val, const char *str); int str2offset(curl_off_t *val, const char *str);
void checkpasswd(const char *kind, char **userpwd); ParameterError checkpasswd(const char *kind, char **userpwd);
ParameterError add2list(struct curl_slist **list, const char *ptr); ParameterError add2list(struct curl_slist **list, const char *ptr);
@@ -47,7 +47,5 @@ int ftpcccmethod(struct Configurable *config, const char *str);
long delegation(struct Configurable *config, char *str); long delegation(struct Configurable *config, char *str);
#endif /* HEADER_CURL_TOOL_PARAMHLP_H */ #endif /* HEADER_CURL_TOOL_PARAMHLP_H */