- Jeff Pohlmeyer found out that if you ask libcurl to load a cookiefile (with

CURLOPT_COOKIEFILE), add a cookie (with CURLOPT_COOKIELIST), tell it to
  write the result to a given cookie jar and then never actually call
  curl_easy_perform() - the given file(s) to read was never read but the
  output file was written and thus it caused a "funny" result.

- While doing some tests for the bug above, I noticed that Firefox generates
  large numbers (for the expire time) in the cookies.txt file and libcurl
  didn't treat them properly. Now it does.
This commit is contained in:
Daniel Stenberg 2005-08-17 08:55:43 +00:00
parent 362912ff83
commit a676c18502
6 changed files with 87 additions and 59 deletions

11
CHANGES
View File

@ -7,6 +7,17 @@
Changelog
Daniel (17 August 2005)
- Jeff Pohlmeyer found out that if you ask libcurl to load a cookiefile (with
CURLOPT_COOKIEFILE), add a cookie (with CURLOPT_COOKIELIST), tell it to
write the result to a given cookie jar and then never actually call
curl_easy_perform() - the given file(s) to read was never read but the
output file was written and thus it caused a "funny" result.
- While doing some tests for the bug above, I noticed that Firefox generates
large numbers (for the expire time) in the cookies.txt file and libcurl
didn't treat them properly. Now it does.
Daniel (15 August 2005)
- Added more verbose "warning" messages to the curl client for cases where it
fails to open/read files etc to help users diagnose why it doesn't do what

View File

@ -59,6 +59,6 @@ advice from friends like these:
John McGowan, Georg Wicherski, Andres Garcia, Eric Cooper, Todd Kulesza,
Tupone Alfredo, Gisle Vanem, David Shaw, Andrew Bushnell, Dan Fandrich,
Adrian Schuur, Diego Casorran, Peteris Krumins, Jon Grubbs, Christopher
R. Palmer, Mario Schroeder, Richard Clayton, James Bursa
R. Palmer, Mario Schroeder, Richard Clayton, James Bursa, Jeff Pohlmeyer
Thanks! (and sorry if I forgot to mention someone)

View File

@ -94,6 +94,8 @@ Example set of cookies:
#include "strtok.h"
#include "sendf.h"
#include "memory.h"
#include "share.h"
#include "strtoofft.h"
/* The last #include file should be: */
#ifdef CURLDEBUG
@ -133,6 +135,27 @@ static bool tailmatch(const char *little, const char *bigone)
return (bool)strequal(little, bigone+biglen-littlelen);
}
/*
* Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
*/
void Curl_cookie_loadfiles(struct SessionHandle *data)
{
struct curl_slist *list = data->change.cookielist;
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);
list = list->next;
}
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
curl_slist_free_all(data->change.cookielist); /* clean up list */
data->change.cookielist = NULL; /* don't do this again! */
}
}
/****************************************************************************
*
* Curl_cookie_add()
@ -473,7 +496,7 @@ Curl_cookie_add(struct SessionHandle *data,
co->secure = (bool)strequal(ptr, "TRUE");
break;
case 4:
co->expires = atoi(ptr);
co->expires = curlx_strtoofft(ptr, NULL, 10);
break;
case 5:
co->name = strdup(ptr);
@ -832,7 +855,7 @@ static char *get_netscape_format(const struct Cookie *co)
"%s\t" /* tailmatch */
"%s\t" /* path */
"%s\t" /* secure */
"%u\t" /* expires */
"%" FORMAT_OFF_T "\t" /* expires */
"%s\t" /* name */
"%s", /* value */
/* Make sure all domains are prefixed with a dot if they allow
@ -842,7 +865,7 @@ static char *get_netscape_format(const struct Cookie *co)
co->tailmatch?"TRUE":"FALSE",
co->path?co->path:"/",
co->secure?"TRUE":"FALSE",
(unsigned int)co->expires,
co->expires,
co->name,
co->value?co->value:"");
}

View File

@ -38,7 +38,7 @@ struct Cookie {
char *value; /* name = <this> */
char *path; /* path = <this> */
char *domain; /* domain = <this> */
long expires; /* expires = <this> */
curl_off_t expires; /* expires = <this> */
char *expirestr; /* the plain text version */
bool tailmatch; /* weather we do tail-matchning of the domain name */
@ -94,8 +94,10 @@ int Curl_cookie_output(struct CookieInfo *, char *);
#if defined(CURL_DISABLE_HTTP) || defined(CURL_DISABLE_COOKIES)
#define Curl_cookie_list(x) NULL
#define Curl_cookie_loadfiles(x)
#else
struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
void Curl_cookie_loadfiles(struct SessionHandle *data);
#endif
#endif

View File

@ -1641,25 +1641,9 @@ CURLcode Curl_pretransfer(struct SessionHandle *data)
data->state.authhost.want = data->set.httpauth;
data->state.authproxy.want = data->set.proxyauth;
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
/* If there was a list of cookie files to read and we haven't done it before,
do it now! */
if(data->change.cookielist) {
struct curl_slist *list = data->change.cookielist;
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);
list = list->next;
}
Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
curl_slist_free_all(data->change.cookielist); /* clean up list */
data->change.cookielist = NULL; /* don't do this again! */
}
#endif /* CURL_DISABLE_HTTP */
/* If there is a list of cookie files to read, do it now! */
if(data->change.cookielist)
Curl_cookie_loadfiles(data);
/* Allow data->set.use_port to set which port to use. This needs to be
* disabled for example when we follow Location: headers to URLs using

View File

@ -227,16 +227,24 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_safefree(data->state.headerbuff);
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
if(data->change.cookielist) /* clean up list if any */
curl_slist_free_all(data->change.cookielist);
Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
if(data->set.cookiejar) {
if(data->change.cookielist)
/* If there is a list of cookie files to read, do it first so that
we have all the told files read before we write the new jar */
Curl_cookie_loadfiles(data);
/* we have a "destination" for all the cookies to get dumped to */
if(Curl_cookie_output(data->cookies, data->set.cookiejar))
infof(data, "WARNING: failed to save cookies in %s\n",
data->set.cookiejar);
}
else {
if(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 */
}
if( !data->share || (data->cookies != data->share->cookies) ) {
Curl_cookie_cleanup(data->cookies);
@ -2951,44 +2959,44 @@ static CURLcode CreateConnection(struct SessionHandle *data,
char proxypasswd[MAX_CURL_PASSWORD_LENGTH];
if(2 == sscanf(proxyptr,
"%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
proxyuser, proxypasswd)) {
CURLcode res = CURLE_OK;
"%" MAX_CURL_USER_LENGTH_TXT"[^:]:"
"%" MAX_CURL_PASSWORD_LENGTH_TXT "[^@]",
proxyuser, proxypasswd)) {
CURLcode res = CURLE_OK;
/* found user and password, rip them out. note that we are
unescaping them, as there is otherwise no way to have a
username or password with reserved characters like ':' in
them. */
Curl_safefree(conn->proxyuser);
conn->proxyuser = curl_unescape(proxyuser,0);
/* found user and password, rip them out. note that we are
unescaping them, as there is otherwise no way to have a
username or password with reserved characters like ':' in
them. */
Curl_safefree(conn->proxyuser);
conn->proxyuser = curl_unescape(proxyuser,0);
if(!conn->proxyuser)
res = CURLE_OUT_OF_MEMORY;
else {
Curl_safefree(conn->proxypasswd);
conn->proxypasswd = curl_unescape(proxypasswd,0);
if(!conn->proxyuser)
res = CURLE_OUT_OF_MEMORY;
else {
Curl_safefree(conn->proxypasswd);
conn->proxypasswd = curl_unescape(proxypasswd,0);
if(!conn->proxypasswd)
res = CURLE_OUT_OF_MEMORY;
}
if(!conn->proxypasswd)
res = CURLE_OUT_OF_MEMORY;
}
if(CURLE_OK == res) {
conn->bits.proxy_user_passwd = TRUE; /* enable it */
atsign = strdup(atsign+1); /* the right side of the @-letter */
if(CURLE_OK == res) {
conn->bits.proxy_user_passwd = TRUE; /* enable it */
atsign = strdup(atsign+1); /* the right side of the @-letter */
if(atsign) {
free(proxydup); /* free the former proxy string */
proxydup = proxyptr = atsign; /* now use this instead */
}
else
res = CURLE_OUT_OF_MEMORY;
}
if(atsign) {
free(proxydup); /* free the former proxy string */
proxydup = proxyptr = atsign; /* now use this instead */
}
else
res = CURLE_OUT_OF_MEMORY;
}
if(res) {
free(proxydup); /* free the allocated proxy string */
return res;
}
if(res) {
free(proxydup); /* free the allocated proxy string */
return res;
}
}
}