diff options
author | Brad King <brad.king@kitware.com> | 2018-10-22 16:55:14 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2018-10-22 16:55:14 (GMT) |
commit | ec13ba36b5398f1d561d6e72d8e253d0eb3c2b5e (patch) | |
tree | beb2cf13c007254d5daefa4bd929ce70520e890c /Utilities/cmcurl/lib/cookie.c | |
parent | 8b5cd17000a6fcf3cf9637c4a5048a7a91fc68e3 (diff) | |
parent | 031002456381245f88f64b0826798b1e249e8e39 (diff) | |
download | CMake-ec13ba36b5398f1d561d6e72d8e253d0eb3c2b5e.zip CMake-ec13ba36b5398f1d561d6e72d8e253d0eb3c2b5e.tar.gz CMake-ec13ba36b5398f1d561d6e72d8e253d0eb3c2b5e.tar.bz2 |
Merge branch 'update-curl' into release-3.13
Merge-request: !2509
Diffstat (limited to 'Utilities/cmcurl/lib/cookie.c')
-rw-r--r-- | Utilities/cmcurl/lib/cookie.c | 130 |
1 files changed, 83 insertions, 47 deletions
diff --git a/Utilities/cmcurl/lib/cookie.c b/Utilities/cmcurl/lib/cookie.c index 2c028b3..da49c2a 100644 --- a/Utilities/cmcurl/lib/cookie.c +++ b/Utilities/cmcurl/lib/cookie.c @@ -40,7 +40,7 @@ struct Cookie *Curl_cookie_add(struct Curl_easy *data, received from a server. The function need to replace previously stored lines that this new - line superceeds. + line supersedes. It may remove lines that are expired. @@ -84,12 +84,9 @@ Example set of cookies: #if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES) -#ifdef USE_LIBPSL -# include <libpsl.h> -#endif - #include "urldata.h" #include "cookie.h" +#include "psl.h" #include "strtok.h" #include "sendf.h" #include "slist.h" @@ -253,9 +250,9 @@ static const char *get_top_domain(const char * const domain, size_t *outlen) len = strlen(domain); last = memrchr(domain, '.', len); if(last) { - first = memrchr(domain, '.', (size_t) (last - domain)); + first = memrchr(domain, '.', (last - domain)); if(first) - len -= (size_t) (++first - domain); + len -= (++first - domain); } if(outlen) @@ -379,13 +376,13 @@ static void strstore(char **str, const char *newstr) */ static void remove_expired(struct CookieInfo *cookies) { - struct Cookie *co, *nx, *pv; + struct Cookie *co, *nx; curl_off_t now = (curl_off_t)time(NULL); unsigned int i; for(i = 0; i < COOKIE_HASH_SIZE; i++) { + struct Cookie *pv = NULL; co = cookies->cookies[i]; - pv = NULL; while(co) { nx = co->next; if(co->expires && co->expires < now) { @@ -406,6 +403,12 @@ static void remove_expired(struct CookieInfo *cookies) } } +/* Make sure domain contains a dot or is localhost. */ +static bool bad_domain(const char *domain) +{ + return !strchr(domain, '.') && !strcasecompare(domain, "localhost"); +} + /**************************************************************************** * * Curl_cookie_add() @@ -442,10 +445,6 @@ Curl_cookie_add(struct Curl_easy *data, bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */ size_t myhash; -#ifdef USE_LIBPSL - const psl_ctx_t *psl; -#endif - #ifdef CURL_DISABLE_VERBOSE_STRINGS (void)data; #endif @@ -497,7 +496,7 @@ Curl_cookie_add(struct Curl_easy *data, name + contents. Chrome and Firefox support 4095 or 4096 bytes combo. */ freecookie(co); - infof(data, "oversized cookie dropped, name/val %d + %d bytes\n", + infof(data, "oversized cookie dropped, name/val %zu + %zu bytes\n", nlen, len); return NULL; } @@ -585,13 +584,8 @@ Curl_cookie_add(struct Curl_easy *data, * TLD or otherwise "protected" suffix. To reduce risk, we require a * dot OR the exact host name being "localhost". */ - { - const char *dotp; - /* check for more dots */ - dotp = strchr(whatptr, '.'); - if(!dotp && !strcasecompare("localhost", whatptr)) - domain = ":"; - } + if(bad_domain(whatptr)) + domain = ":"; #endif is_ip = isip(domain ? domain : whatptr); @@ -723,9 +717,9 @@ Curl_cookie_add(struct Curl_easy *data, if(!queryp) endslash = strrchr(path, '/'); else - endslash = memrchr(path, '/', (size_t)(queryp - path)); + endslash = memrchr(path, '/', (queryp - path)); if(endslash) { - size_t pathlen = (size_t)(endslash-path + 1); /* include end slash */ + size_t pathlen = (endslash-path + 1); /* include end slash */ co->path = malloc(pathlen + 1); /* one extra for the zero byte */ if(co->path) { memcpy(co->path, path, pathlen); @@ -880,9 +874,10 @@ Curl_cookie_add(struct Curl_easy *data, } co->livecookie = c->running; + co->creationtime = ++c->lastct; /* now, we have parsed the incoming line, we must now check if this - superceeds an already existing cookie, which it may if the previous have + supersedes an already existing cookie, which it may if the previous have the same domain and path as this */ /* at first, remove expired cookies */ @@ -890,14 +885,21 @@ Curl_cookie_add(struct Curl_easy *data, remove_expired(c); #ifdef USE_LIBPSL - /* Check if the domain is a Public Suffix and if yes, ignore the cookie. - This needs a libpsl compiled with builtin data. */ + /* Check if the domain is a Public Suffix and if yes, ignore the cookie. */ if(domain && co->domain && !isip(co->domain)) { - psl = psl_builtin(); - if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) { - infof(data, - "cookie '%s' dropped, domain '%s' must not set cookies for '%s'\n", - co->name, domain, co->domain); + const psl_ctx_t *psl = Curl_psl_use(data); + int acceptable; + + if(psl) { + acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain); + Curl_psl_release(data); + } + else + acceptable = !bad_domain(domain); + + if(!acceptable) { + infof(data, "cookie '%s' dropped, domain '%s' must not " + "set cookies for '%s'\n", co->name, domain, co->domain); freecookie(co); return NULL; } @@ -951,6 +953,9 @@ Curl_cookie_add(struct Curl_easy *data, if(replace_old) { co->next = clist->next; /* get the next-pointer first */ + /* when replacing, creationtime is kept from old */ + co->creationtime = clist->creationtime; + /* then free all the old pointers */ free(clist->name); free(clist->value); @@ -1140,12 +1145,24 @@ static int cookie_sort(const void *p1, const void *p2) if(l1 != l2) return (l2 > l1) ? 1 : -1 ; /* avoid size_t <=> int conversions */ - /* 3 - compare cookie names */ - if(c1->name && c2->name) - return strcmp(c1->name, c2->name); + /* 3 - compare cookie name lengths */ + l1 = c1->name ? strlen(c1->name) : 0; + l2 = c2->name ? strlen(c2->name) : 0; - /* sorry, can't be more deterministic */ - return 0; + if(l1 != l2) + return (l2 > l1) ? 1 : -1; + + /* 4 - compare cookie creation time */ + return (c2->creationtime > c1->creationtime) ? 1 : -1; +} + +/* sort cookies only according to creation time */ +static int cookie_sort_ct(const void *p1, const void *p2) +{ + struct Cookie *c1 = *(struct Cookie **)p1; + struct Cookie *c2 = *(struct Cookie **)p2; + + return (c2->creationtime > c1->creationtime) ? 1 : -1; } #define CLONE(field) \ @@ -1174,6 +1191,7 @@ static struct Cookie *dup_cookie(struct Cookie *src) d->secure = src->secure; d->livecookie = src->livecookie; d->httponly = src->httponly; + d->creationtime = src->creationtime; } return d; @@ -1384,9 +1402,8 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies) ****************************************************************************/ void Curl_cookie_cleanup(struct CookieInfo *c) { - unsigned int i; - if(c) { + unsigned int i; free(c->filename); for(i = 0; i < COOKIE_HASH_SIZE; i++) Curl_cookie_freelist(c->cookies[i]); @@ -1439,6 +1456,8 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) bool use_stdout = FALSE; char *format_ptr; unsigned int i; + unsigned int j; + struct Cookie **array; if((NULL == c) || (0 == c->numcookies)) /* If there are no known cookies, we don't write or even create any @@ -1452,6 +1471,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) if(0 == c->numcookies) return 0; + array = malloc(sizeof(struct Cookie *) * c->numcookies); + if(!array) + return 1; + if(!strcmp("-", dumphere)) { /* use stdout */ out = stdout; @@ -1459,8 +1482,10 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) } else { out = fopen(dumphere, FOPEN_WRITETEXT); - if(!out) + if(!out) { + free(array); return 1; /* failure */ + } } fputs("# Netscape HTTP Cookie File\n" @@ -1468,22 +1493,33 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere) "# This file was generated by libcurl! Edit at your own risk.\n\n", out); + j = 0; for(i = 0; i < COOKIE_HASH_SIZE; i++) { for(co = c->cookies[i]; co; co = co->next) { if(!co->domain) continue; - format_ptr = get_netscape_format(co); - if(format_ptr == NULL) { - fprintf(out, "#\n# Fatal libcurl error\n"); - if(!use_stdout) - fclose(out); - return 1; + array[j++] = co; + } + } + + qsort(array, c->numcookies, sizeof(struct Cookie *), cookie_sort_ct); + + for(i = 0; i < j; i++) { + format_ptr = get_netscape_format(array[i]); + if(format_ptr == NULL) { + fprintf(out, "#\n# Fatal libcurl error\n"); + if(!use_stdout) { + free(array); + fclose(out); } - fprintf(out, "%s\n", format_ptr); - free(format_ptr); + return 1; } + fprintf(out, "%s\n", format_ptr); + free(format_ptr); } + free(array); + if(!use_stdout) fclose(out); |