1
0
mirror of https://github.com/moparisthebest/curl synced 2024-12-21 23:58:49 -05:00

libcurl: some OOM handling fixes

This commit is contained in:
Yang Tse 2011-10-07 20:50:57 +02:00
parent b82bd05354
commit 17f48fe879
13 changed files with 118 additions and 52 deletions

View File

@ -1107,23 +1107,20 @@ struct curl_slist *Curl_cookie_list(struct SessionHandle *data)
c = data->cookies->cookies;
beg = list;
while(c) {
/* fill the list with _all_ the cookies we know */
line = get_netscape_format(c);
if(line == NULL) {
curl_slist_free_all(beg);
if(!line) {
curl_slist_free_all(list);
return NULL;
}
list = curl_slist_append(list, line);
beg = curl_slist_append(list, line);
free(line);
if(list == NULL) {
curl_slist_free_all(beg);
if(!beg) {
curl_slist_free_all(list);
return NULL;
}
else if(beg == NULL) {
beg = list;
}
list = beg;
c = c->next;
}
@ -1148,10 +1145,12 @@ void Curl_flush_cookies(struct SessionHandle *data, int cleanup)
data->set.str[STRING_COOKIEJAR]);
}
else {
if(cleanup && data->change.cookielist)
if(cleanup && data->change.cookielist) {
/* since nothing is written, we can just free the list of cookie file
names */
curl_slist_free_all(data->change.cookielist); /* clean up list */
data->change.cookielist = NULL;
}
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
}

View File

@ -676,16 +676,15 @@ CURL *curl_easy_duphandle(CURL *incurl)
if(outcurl) {
if(outcurl->state.connc &&
(outcurl->state.connc->type == CONNCACHE_PRIVATE))
(outcurl->state.connc->type == CONNCACHE_PRIVATE)) {
Curl_rm_connc(outcurl->state.connc);
if(outcurl->state.headerbuff)
free(outcurl->state.headerbuff);
if(outcurl->change.cookielist)
curl_slist_free_all(outcurl->change.cookielist);
if(outcurl->change.url)
free(outcurl->change.url);
if(outcurl->change.referer)
free(outcurl->change.referer);
outcurl->state.connc = NULL;
}
curl_slist_free_all(outcurl->change.cookielist);
outcurl->change.cookielist = NULL;
Curl_safefree(outcurl->state.headerbuff);
Curl_safefree(outcurl->change.url);
Curl_safefree(outcurl->change.referer);
Curl_freeset(outcurl);
free(outcurl);
}

View File

@ -72,9 +72,12 @@ Curl_hash_init(struct curl_hash *h,
for(i = 0; i < slots; ++i) {
h->table[i] = Curl_llist_alloc((curl_llist_dtor) hash_element_dtor);
if(!h->table[i]) {
while(i--)
while(i--) {
Curl_llist_destroy(h->table[i], NULL);
h->table[i] = NULL;
}
free(h->table);
h->table = NULL;
return 1; /* failure */
}
}
@ -240,6 +243,7 @@ Curl_hash_clean(struct curl_hash *h)
}
free(h->table);
h->table = NULL;
}
void

View File

@ -131,6 +131,10 @@ Curl_llist_remove(struct curl_llist *list, struct curl_llist_element *e,
list->dtor(user, e->ptr);
e->ptr = NULL;
e->prev = NULL;
e->next = NULL;
free(e);
--list->size;

View File

@ -1804,6 +1804,7 @@ CURLMcode curl_multi_cleanup(CURLM *multi_handle)
/* remove the pending list of messages */
Curl_llist_destroy(multi->msglist, NULL);
multi->msglist = NULL;
/* remove all easy handles */
easy = multi->easy.next;

View File

@ -119,10 +119,7 @@ void curl_slist_free_all(struct curl_slist *list)
item = list;
do {
next = item->next;
if(item->data) {
free(item->data);
}
Curl_safefree(item->data);
free(item);
item = next;
} while(next);

View File

@ -504,9 +504,12 @@ void Curl_ssl_free_certinfo(struct SessionHandle *data)
struct curl_certinfo *ci = &data->info.certs;
if(ci->num_of_certs) {
/* free all individual lists used */
for(i=0; i<ci->num_of_certs; i++)
for(i=0; i<ci->num_of_certs; i++) {
curl_slist_free_all(ci->certinfo[i]);
ci->certinfo[i] = NULL;
}
free(ci->certinfo); /* free the actual array too */
ci->certinfo = NULL;
ci->num_of_certs = 0;
}
}

View File

@ -810,18 +810,16 @@ struct curl_slist *Curl_ossl_engines_list(struct SessionHandle *data)
{
struct curl_slist *list = NULL;
#if defined(USE_SSLEAY) && defined(HAVE_OPENSSL_ENGINE_H)
struct curl_slist *beg = NULL;
struct curl_slist *beg;
ENGINE *e;
for(e = ENGINE_get_first(); e; e = ENGINE_get_next(e)) {
list = curl_slist_append(list, ENGINE_get_id(e));
if(list == NULL) {
curl_slist_free_all(beg);
beg = curl_slist_append(list, ENGINE_get_id(e));
if(!beg) {
curl_slist_free_all(list);
return NULL;
}
else if(beg == NULL) {
beg = list;
}
list = beg;
}
#endif
(void) data;
@ -1859,6 +1857,7 @@ static CURLcode push_certinfo_len(struct SessionHandle *data,
nl = curl_slist_append(ci->certinfo[certnum], output);
if(!nl) {
curl_slist_free_all(ci->certinfo[certnum]);
ci->certinfo[certnum] = NULL;
res = CURLE_OUT_OF_MEMORY;
}
else

View File

@ -763,18 +763,25 @@ static void printsub(struct SessionHandle *data,
static CURLcode check_telnet_options(struct connectdata *conn)
{
struct curl_slist *head;
struct curl_slist *beg;
char option_keyword[128];
char option_arg[256];
char *buf;
struct SessionHandle *data = conn->data;
struct TELNET *tn = (struct TELNET *)conn->data->state.proto.telnet;
CURLcode result = CURLE_OK;
/* Add the user name as an environment variable if it
was given on the command line */
if(conn->bits.user_passwd) {
snprintf(option_arg, sizeof(option_arg), "USER,%s", conn->user);
tn->telnet_vars = curl_slist_append(tn->telnet_vars, option_arg);
beg = curl_slist_append(tn->telnet_vars, option_arg);
if(!beg) {
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
return CURLE_OUT_OF_MEMORY;
}
tn->telnet_vars = beg;
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
}
@ -800,24 +807,33 @@ static CURLcode check_telnet_options(struct connectdata *conn)
/* Environment variable */
if(Curl_raw_equal(option_keyword, "NEW_ENV")) {
buf = strdup(option_arg);
if(!buf)
return CURLE_OUT_OF_MEMORY;
tn->telnet_vars = curl_slist_append(tn->telnet_vars, buf);
beg = curl_slist_append(tn->telnet_vars, option_arg);
if(!beg) {
result = CURLE_OUT_OF_MEMORY;
break;
}
tn->telnet_vars = beg;
tn->us_preferred[CURL_TELOPT_NEW_ENVIRON] = CURL_YES;
continue;
}
failf(data, "Unknown telnet option %s", head->data);
return CURLE_UNKNOWN_TELNET_OPTION;
result = CURLE_UNKNOWN_TELNET_OPTION;
break;
}
else {
failf(data, "Syntax error in telnet option: %s", head->data);
return CURLE_TELNET_OPTION_SYNTAX;
result = CURLE_TELNET_OPTION_SYNTAX;
break;
}
}
return CURLE_OK;
if(result) {
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
}
return result;
}
/*
@ -1109,6 +1125,7 @@ static CURLcode telnet_done(struct connectdata *conn,
(void)premature; /* not used */
curl_slist_free_all(tn->telnet_vars);
tn->telnet_vars = NULL;
free(conn->data->state.proto.telnet);
conn->data->state.proto.telnet = NULL;

View File

@ -2569,6 +2569,11 @@ static void conn_free(struct connectdata *conn)
Curl_llist_destroy(conn->pend_pipe, NULL);
Curl_llist_destroy(conn->done_pipe, NULL);
conn->send_pipe = NULL;
conn->recv_pipe = NULL;
conn->pend_pipe = NULL;
conn->done_pipe = NULL;
Curl_safefree(conn->localdev);
Curl_free_ssl_config(&conn->ssl_config);
@ -3583,6 +3588,12 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
Curl_llist_destroy(conn->recv_pipe, NULL);
Curl_llist_destroy(conn->pend_pipe, NULL);
Curl_llist_destroy(conn->done_pipe, NULL);
conn->send_pipe = NULL;
conn->recv_pipe = NULL;
conn->pend_pipe = NULL;
conn->done_pipe = NULL;
Curl_safefree(conn->master_buffer);
Curl_safefree(conn->localdev);
Curl_safefree(conn);
@ -4650,10 +4661,17 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->passwd);
Curl_safefree(old_conn->proxyuser);
Curl_safefree(old_conn->proxypasswd);
Curl_llist_destroy(old_conn->send_pipe, NULL);
Curl_llist_destroy(old_conn->recv_pipe, NULL);
Curl_llist_destroy(old_conn->pend_pipe, NULL);
Curl_llist_destroy(old_conn->done_pipe, NULL);
old_conn->send_pipe = NULL;
old_conn->recv_pipe = NULL;
old_conn->pend_pipe = NULL;
old_conn->done_pipe = NULL;
Curl_safefree(old_conn->master_buffer);
}

View File

@ -109,7 +109,7 @@ char *sanitize_dos_name(char *file_name)
strcpy(new_name, msdosify(file_name));
free(file_name);
Curl_safefree(file_name);
return strdup(rename_if_dos_device_name(new_name));
}
@ -288,7 +288,7 @@ CURLcode FindWin32CACert(struct Configurable *config, const char *bundle_file)
else
result = CURLE_SSL_CACERT;
free(buf);
Curl_safefree(buf);
}
return result;

View File

@ -971,7 +971,7 @@ int operate(struct Configurable *config, int argc, argv_item_t argv[])
/* libssh2 version older than 1.1.1 */
res = CURLE_OK;
}
free(home);
Curl_safefree(home);
}
if(res)
goto show_error;

View File

@ -49,23 +49,45 @@ static int init(CURLM *cm, const char* url, const char* userpwd,
}
res = curl_easy_setopt(eh, CURLOPT_URL, url);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_PROXY, PROXY);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_PROXYUSERPWD, userpwd);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_PROXYAUTH, (long)CURLAUTH_ANY);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_VERBOSE, 1L);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_HEADER, 1L);
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
res = curl_easy_setopt(eh, CURLOPT_HTTPHEADER, headers); /* custom Host: */
if(res) return 1;
if(res) {
curl_easy_cleanup(eh);
return 1;
}
if ((res = (int)curl_multi_add_handle(cm, eh)) != CURLM_OK) {
fprintf(stderr, "curl_multi_add_handle() failed, "
"with code %d\n", res);
curl_easy_cleanup(eh);
return 1; /* failure */
}
@ -80,13 +102,16 @@ static int loop(CURLM *cm, const char* url, const char* userpwd,
int M, Q, U = -1;
fd_set R, W, E;
struct timeval T;
CURLMcode rc;
if(init(cm, url, userpwd, headers))
return 1; /* failure */
while (U) {
(void) curl_multi_perform(cm, &U);
rc = curl_multi_perform(cm, &U);
if(rc == CURLM_OUT_OF_MEMORY)
return 1; /* failure */
if (U) {
FD_ZERO(&R);