From 1cf6c15ab43ce41fa99e3776d0c23ed4f66196a8 Mon Sep 17 00:00:00 2001 From: Daniel Stenberg Date: Mon, 25 May 2009 12:23:22 +0000 Subject: - 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. --- lib/cookie.c | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'lib/cookie.c') 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 = pair */ + /* this is a = 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; -- cgit v1.2.3