diff --git a/CHANGES b/CHANGES index 1c8ac5bf9..6b68f6cee 100644 --- a/CHANGES +++ b/CHANGES @@ -6,6 +6,12 @@ Changelog +Daniel Stenberg (26 Sep 2009) +- John P. McCaskey posted a bug report that showed how libcurl did wrong when + saving received cookies with no given path, if the path in the request had a + query part. That is means a question mark (?) and characters on the right + side of that. I wrote test case 1105 and fixed this problem. + Kamil Dudka (26 Sep 2009) - Implemented a protocol independent way to specify blocking direction, used by transfer.c for blocking. It is currently used only by SCP and SFTP protocols. diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 519587bc9..b8b46a61e 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -30,6 +30,8 @@ This release includes the following bugfixes: o cookie expiry date at 1970-jan-1 00:00:00 o libcurl-OpenSSL failed to verify some certs with Subject Alternative Name o libcurl-OpenSSL can load CRL files with more than one certificate inside + o received cookies without explicit path got saved wrong if the URL had a + query part This release includes the following known bugs: @@ -40,6 +42,6 @@ advice from friends like these: Karl Moerder, Kamil Dudka, Krister Johansen, Andre Guibert de Bruet, Michal Marek, Eric Wong, Guenter Knauf, Peter Sylvester, Daniel Johnson, - Claes Jakobsson, Sven Anders, Chris Mumford + Claes Jakobsson, Sven Anders, Chris Mumford, John P. McCaskey Thanks! (and sorry if I forgot to mention someone) diff --git a/lib/cookie.c b/lib/cookie.c index b79d1b07b..13941857c 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -167,6 +167,24 @@ static void strstore(char **str, const char *newstr) *str = strdup(newstr); } + +/* + * The memrchr() function is like the memchr() function, except that it + * searches backwards from the end of the n bytes pointed to by s instead of + * forwards from the front. + * + * Exists in glibc but is not widely available on other systems. + */ +static void *memrchr(const char *s, int c, size_t n) +{ + while(n--) { + if(s[n] == c) + return &s[n]; + } + return NULL; +} + + /**************************************************************************** * * Curl_cookie_add() @@ -186,8 +204,8 @@ Curl_cookie_add(struct SessionHandle *data, char *lineptr, /* first character of the line */ const char *domain, /* default domain */ const char *path) /* full path used when this cookie is set, - used to get default path for the cookie - unless set */ + used to get default path for the cookie + unless set */ { struct Cookie *clist; char name[MAX_NAME]; @@ -429,8 +447,18 @@ Curl_cookie_add(struct SessionHandle *data, } if(!badcookie && !co->path && path) { - /* no path was given in the header line, set the default */ - char *endslash = strrchr(path, '/'); + /* No path was given in the header line, set the default. + Note that the passed-in path to this function MAY have a '?' and + following part that MUST not be stored as part of the path. */ + char *queryp = strchr(path, '?'); + + /* queryp is where the interesting part of the path ends, so now we + want to the find the last */ + char *endslash; + if(!queryp) + endslash = strrchr(path, '/'); + else + endslash = memrchr(path, '/', queryp - path); if(endslash) { size_t pathlen = endslash-path+1; /* include the ending slash */ co->path=malloc(pathlen+1); /* one extra for the zero byte */ diff --git a/tests/data/DISABLED b/tests/data/DISABLED index a7509a9da..e3a9130f6 100644 --- a/tests/data/DISABLED +++ b/tests/data/DISABLED @@ -5,4 +5,4 @@ # Lines starting with '#' letters are treated as comments. 563 564 -1105 + diff --git a/tests/data/test1105 b/tests/data/test1105 index e1dbebb6d..1a8f896a7 100644 --- a/tests/data/test1105 +++ b/tests/data/test1105 @@ -55,10 +55,9 @@ userid=myname&password=mypassword # http://curl.haxx.se/rfc/cookie_spec.html # This file was generated by libcurl! Edit at your own risk. -127.0.0.1 FALSE /we/want FALSE 0 foobar name +127.0.0.1 FALSE /we/want/ FALSE 0 foobar name .127.0.0.1 TRUE "/silly/" FALSE 0 mismatch this .0.0.1 TRUE / FALSE 0 partmatch present -