diff options
-rw-r--r-- | CHANGES | 7 | ||||
-rw-r--r-- | RELEASE-NOTES | 1 | ||||
-rw-r--r-- | lib/cookie.c | 29 | ||||
-rw-r--r-- | tests/data/test8 | 1 |
4 files changed, 31 insertions, 7 deletions
@@ -6,6 +6,13 @@ Changelog +Daniel Stenberg (25 May 2009) +- bug report #2796358 (http://curl.haxx.se/bug/view.cgi?id=2796358) pointed + out that the cookie parser would leak memory when it parses cookies that are + received with domain, path etc set multiple times in the same header. While + such a cookie is questionable, they occur in the wild and libcurl no longer + leaks memory for them. I added such a header to test case 8. + Daniel Fandrich (22 May 2009) - Removed some obsolete digest code that caused a valgrind error in test 551. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 6388ea575..58deec113 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -14,6 +14,7 @@ This release includes the following changes: This release includes the following bugfixes: o crash on bad socket close with FTP + o leaking cookie memory when duplicate domains or paths were used This release includes the following known bugs: diff --git a/lib/cookie.c b/lib/cookie.c index 6a8813062..241f7ff3f 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -156,6 +156,19 @@ void Curl_cookie_loadfiles(struct SessionHandle *data) } } +/* + * strstore() makes a strdup() on the 'newstr' and if '*str' is non-NULL + * that will be freed before the allocated string is stored there. + * + * It is meant to easily replace strdup() + */ +static void strstore(char **str, const char *newstr) +{ + if(*str) + free(*str); + *str = strdup(newstr); +} + /**************************************************************************** * * Curl_cookie_add() @@ -227,7 +240,9 @@ Curl_cookie_add(struct SessionHandle *data, if(1 <= sscanf(ptr, "%" MAX_NAME_TXT "[^;=]=%" MAX_COOKIE_LINE_TXT "[^;\r\n]", name, what)) { - /* this is a <name>=<what> pair */ + /* this is a <name>=<what> pair. We use strstore() below to properly + deal with received cookie headers that have the same string + property set more than once, and then we use the last one. */ const char *whatptr; @@ -245,7 +260,7 @@ Curl_cookie_add(struct SessionHandle *data, } if(Curl_raw_equal("path", name)) { - co->path=strdup(whatptr); + strstore(&co->path, whatptr); if(!co->path) { badcookie = TRUE; /* out of memory bad */ break; @@ -297,8 +312,8 @@ Curl_cookie_add(struct SessionHandle *data, const char *tailptr=whatptr; if(tailptr[0] == '.') tailptr++; - co->domain=strdup(tailptr); /* don't prefix w/dots - internally */ + strstore(&co->domain, tailptr); /* don't prefix w/dots + internally */ if(!co->domain) { badcookie = TRUE; break; @@ -317,7 +332,7 @@ Curl_cookie_add(struct SessionHandle *data, } } else if(Curl_raw_equal("version", name)) { - co->version=strdup(whatptr); + strstore(&co->version, whatptr); if(!co->version) { badcookie = TRUE; break; @@ -333,7 +348,7 @@ Curl_cookie_add(struct SessionHandle *data, cookie should be discarded immediately. */ - co->maxage = strdup(whatptr); + strstore(&co->maxage, whatptr); if(!co->maxage) { badcookie = TRUE; break; @@ -343,7 +358,7 @@ Curl_cookie_add(struct SessionHandle *data, (long)now; } else if(Curl_raw_equal("expires", name)) { - co->expirestr=strdup(whatptr); + strstore(&co->expirestr, whatptr); if(!co->expirestr) { badcookie = TRUE; break; diff --git a/tests/data/test8 b/tests/data/test8 index 3af9c8155..959b8807e 100644 --- a/tests/data/test8 +++ b/tests/data/test8 @@ -38,6 +38,7 @@ Funny-head: yesyes Set-Cookie: foobar=name; domain=127.0.0.1; path=/; Set-Cookie: mismatch=this; domain=127.0.0.1; path="/silly/"; Set-Cookie: partmatch=present; domain=.0.0.1; path=/; +Set-Cookie: duplicate=test; domain=.0.0.1; domain=.0.0.1; path=/donkey; Set-Cookie: cookie=yes; path=/we; Set-Cookie: nocookie=yes; path=/WE; |