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:
parent
b82bd05354
commit
17f48fe879
19
lib/cookie.c
19
lib/cookie.c
@ -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);
|
||||
}
|
||||
|
||||
|
17
lib/easy.c
17
lib/easy.c
@ -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);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
13
lib/ssluse.c
13
lib/ssluse.c
@ -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
|
||||
|
35
lib/telnet.c
35
lib/telnet.c
@ -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;
|
||||
|
18
lib/url.c
18
lib/url.c
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user