diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/cookie.c | 48 |
1 files changed, 47 insertions, 1 deletions
diff --git a/lib/cookie.c b/lib/cookie.c index 7be8fc3c5..3a3edd516 100644 --- a/lib/cookie.c +++ b/lib/cookie.c @@ -5,7 +5,7 @@ * | (__| |_| | _ <| |___ * \___|\___/|_| \_\_____| * - * Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al. + * Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al. * * This software is licensed as described in the file COPYING, which * you should have received as part of this distribution. The terms @@ -774,6 +774,18 @@ struct CookieInfo *Curl_cookie_init(struct SessionHandle *data, return c; } +/* sort this so that the longest path gets before the shorter path */ +static int cookie_sort(const void *p1, const void *p2) +{ + struct Cookie *c1 = *(struct Cookie **)p1; + struct Cookie *c2 = *(struct Cookie **)p2; + + size_t l1 = c1->path?strlen(c1->path):0; + size_t l2 = c2->path?strlen(c2->path):0; + + return l2 - l1; +} + /***************************************************************************** * * Curl_cookie_getlist() @@ -794,6 +806,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, struct Cookie *co; time_t now = time(NULL); struct Cookie *mainco=NULL; + int matches=0; if(!c || !c->cookies) return NULL; /* no cookie struct or no cookies in the struct */ @@ -834,8 +847,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, /* point the main to us */ mainco = newco; + + matches++; } else { + fail: /* failure, clear up the allocated chain and return NULL */ while(mainco) { co = mainco->next; @@ -851,6 +867,36 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, co = co->next; } + if(matches) { + /* Now we need to make sure that if there is a name appearing more than + once, the longest specified path version comes first. To make this + the swiftest way, we just sort them all based on path length. */ + struct Cookie **array; + int i; + + /* alloc an array and store all cookie pointers */ + array = (struct Cookie **)malloc(sizeof(struct Cookie *) * matches); + if(!array) + goto fail; + + co = mainco; + + for(i=0; co; co = co->next) + array[i++] = co; + + /* now sort the cookie pointers in path lenth order */ + qsort(array, matches, sizeof(struct Cookie *), cookie_sort); + + /* remake the linked list order according to the new order */ + + mainco = array[0]; /* start here */ + for(i=0; i<matches-1; i++) + array[i]->next = array[i+1]; + array[matches-1]->next = NULL; /* terminate the list */ + + free(array); /* remove the temporary data again */ + } + return mainco; /* return the new list */ } |