/*
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
- * NOTE: failures are ignored
+ *
+ * NOTE: OOM or cookie parsing failures are ignored.
*/
void Curl_cookie_loadfiles(struct SessionHandle *data)
{
if(list) {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
while(list) {
- data->cookies = Curl_cookie_init(data,
- list->data,
- data->cookies,
- data->set.cookiesession);
+ struct CookieInfo *newcookies = Curl_cookie_init(data,
+ list->data,
+ data->cookies,
+ data->set.cookiesession);
+ if(!newcookies)
+ /* Failure may be due to OOM or a bad cookie; both are ignored
+ * but only the first should be
+ */
+ infof(data, "ignoring failed cookie_init for %s\n", list->data);
+ else
+ data->cookies = newcookies;
list = list->next;
}
curl_slist_free_all(data->change.cookielist); /* clean up list */
* Be aware that sometimes we get an IP-only host name, and that might also be
* a numerical IPv6 address.
*
+ * Returns NULL on out of memory or invalid cookie. This is suboptimal,
+ * as they should be treated separately.
***************************************************************************/
struct Cookie *
*
* If 'newsession' is TRUE, discard all "session cookies" on read from file.
*
+ * Returns NULL on out of memory. Invalid cookies are ignored.
****************************************************************************/
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
const char *file,
bool newsession)
{
struct CookieInfo *c;
- FILE *fp;
+ FILE *fp = NULL;
bool fromfile=TRUE;
+ char *line = NULL;
if(NULL == inc) {
/* we didn't get a struct, create one */
if(!c)
return NULL; /* failed to get memory */
c->filename = strdup(file?file:"none"); /* copy the name just in case */
+ if(!c->filename)
+ goto fail; /* failed to get memory */
}
else {
/* we got an already existing one, use that */
char *lineptr;
bool headerline;
- char *line = malloc(MAX_COOKIE_LINE);
- if(line) {
- while(fgets(line, MAX_COOKIE_LINE, fp)) {
- if(checkprefix("Set-Cookie:", line)) {
- /* This is a cookie line, get it! */
- lineptr=&line[11];
- headerline=TRUE;
- }
- else {
- lineptr=line;
- headerline=FALSE;
- }
- while(*lineptr && ISBLANK(*lineptr))
- lineptr++;
-
- Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
+ line = malloc(MAX_COOKIE_LINE);
+ if(!line)
+ goto fail;
+ while(fgets(line, MAX_COOKIE_LINE, fp)) {
+ if(checkprefix("Set-Cookie:", line)) {
+ /* This is a cookie line, get it! */
+ lineptr=&line[11];
+ headerline=TRUE;
}
- free(line); /* free the line buffer */
+ else {
+ lineptr=line;
+ headerline=FALSE;
+ }
+ while(*lineptr && ISBLANK(*lineptr))
+ lineptr++;
+
+ Curl_cookie_add(data, c, headerline, lineptr, NULL, NULL);
}
+ free(line); /* free the line buffer */
+
if(fromfile)
fclose(fp);
}
c->running = TRUE; /* now, we're running */
return c;
+
+fail:
+ Curl_safefree(line);
+ if(!inc)
+ /* Only clean up if we allocated it here, as the original could still be in
+ * use by a share handle */
+ Curl_cookie_cleanup(c);
+ if(fromfile && fp)
+ fclose(fp);
+ return NULL; /* out of memory */
}
/* sort this so that the longest path gets before the shorter path */
/*
* Set cookie file name to dump all cookies to when we're done.
*/
+ {
+ struct CookieInfo *newcookies;
result = setstropt(&data->set.str[STRING_COOKIEJAR],
va_arg(param, char *));
* Activate the cookie parser. This may or may not already
* have been made.
*/
- data->cookies = Curl_cookie_init(data, NULL, data->cookies,
- data->set.cookiesession);
+ newcookies = Curl_cookie_init(data, NULL, data->cookies,
+ data->set.cookiesession);
+ if(!newcookies)
+ result = CURLE_OUT_OF_MEMORY;
+ data->cookies = newcookies;
+ }
break;
case CURLOPT_COOKIESESSION:
data->cookies = Curl_cookie_init(data, NULL, NULL, TRUE);
argptr = strdup(argptr);
- if(!argptr) {
+ if(!argptr || !data->cookies) {
result = CURLE_OUT_OF_MEMORY;
+ Curl_safefree(argptr);
}
else {
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);