Revert "Imported Upstream version 7.53.1"
[platform/upstream/curl.git] / lib / cookie.c
index 9462843..d5a83fd 100644 (file)
@@ -5,7 +5,7 @@
  *                            | (__| |_| |  _ <| |___
  *                             \___|\___/|_| \_\_____|
  *
- * Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
+ * Copyright (C) 1998 - 2016, 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
@@ -90,12 +90,13 @@ Example set of cookies:
 
 #include "urldata.h"
 #include "cookie.h"
+#include "strequal.h"
 #include "strtok.h"
 #include "sendf.h"
 #include "slist.h"
 #include "share.h"
 #include "strtoofft.h"
-#include "strcase.h"
+#include "rawstr.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
 
@@ -125,7 +126,7 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
   if(hostname_len < cookie_domain_len)
     return FALSE;
 
-  if(!strcasecompare(cooke_domain, hostname+hostname_len-cookie_domain_len))
+  if(!Curl_raw_equal(cooke_domain, hostname+hostname_len-cookie_domain_len))
     return FALSE;
 
   /* A lead char of cookie_domain is not '.'.
@@ -146,12 +147,12 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
  * matching cookie path and url path
  * RFC6265 5.1.4 Paths and Path-Match
  */
-static bool pathmatch(const char *cookie_path, const char *request_uri)
+static bool pathmatch(const char* cookie_path, const char* request_uri)
 {
   size_t cookie_path_len;
   size_t uri_path_len;
-  char *uri_path = NULL;
-  char *pos;
+  charuri_path = NULL;
+  charpos;
   bool ret = FALSE;
 
   /* cookie_path must not have last '/' separator. ex: /sample */
@@ -468,9 +469,9 @@ Curl_cookie_add(struct Curl_easy *data,
           /* this was a "<name>=" with no content, and we must allow
              'secure' and 'httponly' specified this weirdly */
           done = TRUE;
-          if(strcasecompare("secure", name))
+          if(Curl_raw_equal("secure", name))
             co->secure = TRUE;
-          else if(strcasecompare("httponly", name))
+          else if(Curl_raw_equal("httponly", name))
             co->httponly = TRUE;
           else if(sep)
             /* there was a '=' so we're not done parsing this field */
@@ -478,7 +479,7 @@ Curl_cookie_add(struct Curl_easy *data,
         }
         if(done)
           ;
-        else if(strcasecompare("path", name)) {
+        else if(Curl_raw_equal("path", name)) {
           strstore(&co->path, whatptr);
           if(!co->path) {
             badcookie = TRUE; /* out of memory bad */
@@ -490,8 +491,9 @@ Curl_cookie_add(struct Curl_easy *data,
             break;
           }
         }
-        else if(strcasecompare("domain", name)) {
+        else if(Curl_raw_equal("domain", name)) {
           bool is_ip;
+          const char *dotp;
 
           /* Now, we make sure that our host is within the given domain,
              or the given domain is not valid and thus cannot be set. */
@@ -499,23 +501,13 @@ Curl_cookie_add(struct Curl_easy *data,
           if('.' == whatptr[0])
             whatptr++; /* ignore preceding dot */
 
-#ifndef USE_LIBPSL
-          /*
-           * Without PSL we don't know when the incoming cookie is set on a
-           * 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=":";
-          }
-#endif
-
           is_ip = isip(domain ? domain : whatptr);
 
+          /* check for more dots */
+          dotp = strchr(whatptr, '.');
+          if(!dotp)
+            domain=":";
+
           if(!domain
              || (is_ip && !strcmp(whatptr, domain))
              || (!is_ip && tailmatch(whatptr, domain))) {
@@ -537,14 +529,14 @@ Curl_cookie_add(struct Curl_easy *data,
                   whatptr);
           }
         }
-        else if(strcasecompare("version", name)) {
+        else if(Curl_raw_equal("version", name)) {
           strstore(&co->version, whatptr);
           if(!co->version) {
             badcookie = TRUE;
             break;
           }
         }
-        else if(strcasecompare("max-age", name)) {
+        else if(Curl_raw_equal("max-age", name)) {
           /* Defined in RFC2109:
 
              Optional.  The Max-Age attribute defines the lifetime of the
@@ -560,7 +552,7 @@ Curl_cookie_add(struct Curl_easy *data,
             break;
           }
         }
-        else if(strcasecompare("expires", name)) {
+        else if(Curl_raw_equal("expires", name)) {
           strstore(&co->expirestr, whatptr);
           if(!co->expirestr) {
             badcookie = TRUE;
@@ -721,7 +713,7 @@ Curl_cookie_add(struct Curl_easy *data,
            As far as I can see, it is set to true when the cookie says
            .domain.com and to false when the domain is complete www.domain.com
         */
-        co->tailmatch = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
+        co->tailmatch = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 2:
         /* It turns out, that sometimes the file format allows the path
@@ -750,7 +742,7 @@ Curl_cookie_add(struct Curl_easy *data,
         fields++; /* add a field and fall down to secure */
         /* FALLTHROUGH */
       case 3:
-        co->secure = strcasecompare(ptr, "TRUE")?TRUE:FALSE;
+        co->secure = Curl_raw_equal(ptr, "TRUE")?TRUE:FALSE;
         break;
       case 4:
         co->expires = curlx_strtoofft(ptr, NULL, 10);
@@ -807,8 +799,8 @@ Curl_cookie_add(struct Curl_easy *data,
   /* Check if the domain is a Public Suffix and if yes, ignore the cookie.
      This needs a libpsl compiled with builtin data. */
   if(domain && co->domain && !isip(co->domain)) {
-    psl = psl_builtin();
-    if(psl && !psl_is_cookie_domain_acceptable(psl, domain, co->domain)) {
+    if(((psl = psl_builtin()) != NULL)
+        && !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);
@@ -821,12 +813,11 @@ Curl_cookie_add(struct Curl_easy *data,
   clist = c->cookies;
   replace_old = FALSE;
   while(clist) {
-    if(strcasecompare(clist->name, co->name)) {
+    if(Curl_raw_equal(clist->name, co->name)) {
       /* the names are identical */
 
       if(clist->domain && co->domain) {
-        if(strcasecompare(clist->domain, co->domain) &&
-          (clist->tailmatch == co->tailmatch))
+        if(Curl_raw_equal(clist->domain, co->domain))
           /* The domains are identical */
           replace_old=TRUE;
       }
@@ -837,7 +828,7 @@ Curl_cookie_add(struct Curl_easy *data,
         /* the domains were identical */
 
         if(clist->spath && co->spath) {
-          if(strcasecompare(clist->spath, co->spath)) {
+          if(Curl_raw_equal(clist->spath, co->spath)) {
             replace_old = TRUE;
           }
           else
@@ -911,35 +902,6 @@ Curl_cookie_add(struct Curl_easy *data,
   return co;
 }
 
-/*
- * get_line() makes sure to only return complete whole lines that fit in 'len'
- * bytes and end with a newline.
- */
-static char *get_line(char *buf, int len, FILE *input)
-{
-  bool partial = FALSE;
-  while(1) {
-    char *b = fgets(buf, len, input);
-    if(b) {
-      size_t rlen = strlen(b);
-      if(rlen && (b[rlen-1] == '\n')) {
-        if(partial) {
-          partial = FALSE;
-          continue;
-        }
-        return b;
-      }
-      else
-        /* read a partial, discard the next piece that ends with newline */
-        partial = TRUE;
-    }
-    else
-      break;
-  }
-  return NULL;
-}
-
-
 /*****************************************************************************
  *
  * Curl_cookie_init()
@@ -976,7 +938,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
   }
   c->running = FALSE; /* this is not running, this is init */
 
-  if(file && !strcmp(file, "-")) {
+  if(file && strequal(file, "-")) {
     fp = stdin;
     fromfile=FALSE;
   }
@@ -996,7 +958,7 @@ struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
     line = malloc(MAX_COOKIE_LINE);
     if(!line)
       goto fail;
-    while(get_line(line, MAX_COOKIE_LINE, fp)) {
+    while(fgets(line, MAX_COOKIE_LINE, fp)) {
       if(checkprefix("Set-Cookie:", line)) {
         /* This is a cookie line, get it! */
         lineptr=&line[11];
@@ -1061,40 +1023,6 @@ static int cookie_sort(const void *p1, const void *p2)
   return 0;
 }
 
-#define CLONE(field)                     \
-  do {                                   \
-    if(src->field) {                     \
-      d->field = strdup(src->field);     \
-      if(!d->field)                      \
-        goto fail;                       \
-    }                                    \
-  } while(0)
-
-static struct Cookie *dup_cookie(struct Cookie *src)
-{
-  struct Cookie *d = calloc(sizeof(struct Cookie), 1);
-  if(d) {
-    CLONE(expirestr);
-    CLONE(domain);
-    CLONE(path);
-    CLONE(spath);
-    CLONE(name);
-    CLONE(value);
-    CLONE(maxage);
-    CLONE(version);
-    d->expires = src->expires;
-    d->tailmatch = src->tailmatch;
-    d->secure = src->secure;
-    d->livecookie = src->livecookie;
-    d->httponly = src->httponly;
-  }
-  return d;
-
-  fail:
-  freecookie(d);
-  return NULL;
-}
-
 /*****************************************************************************
  *
  * Curl_cookie_getlist()
@@ -1139,7 +1067,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
       /* now check if the domain is correct */
       if(!co->domain ||
          (co->tailmatch && !is_ip && tailmatch(co->domain, host)) ||
-         ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) {
+         ((!co->tailmatch || is_ip) && Curl_raw_equal(host, co->domain)) ) {
         /* the right part of the host matches the domain stuff in the
            cookie data */
 
@@ -1150,8 +1078,11 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
           /* and now, we know this is a match and we should create an
              entry for the return-linked-list */
 
-          newco = dup_cookie(co);
+          newco = malloc(sizeof(struct Cookie));
           if(newco) {
+            /* first, copy the whole source cookie: */
+            memcpy(newco, co, sizeof(struct Cookie));
+
             /* then modify our next */
             newco->next = mainco;
 
@@ -1163,7 +1094,12 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
           else {
             fail:
             /* failure, clear up the allocated chain and return NULL */
-            Curl_cookie_freelist(mainco);
+            while(mainco) {
+              co = mainco->next;
+              free(mainco);
+              mainco = co;
+            }
+
             return NULL;
           }
         }
@@ -1215,7 +1151,7 @@ struct Cookie *Curl_cookie_getlist(struct CookieInfo *c,
 void Curl_cookie_clearall(struct CookieInfo *cookies)
 {
   if(cookies) {
-    Curl_cookie_freelist(cookies->cookies);
+    Curl_cookie_freelist(cookies->cookies, TRUE);
     cookies->cookies = NULL;
     cookies->numcookies = 0;
   }
@@ -1227,14 +1163,21 @@ void Curl_cookie_clearall(struct CookieInfo *cookies)
  *
  * Free a list of cookies previously returned by Curl_cookie_getlist();
  *
+ * The 'cookiestoo' argument tells this function whether to just free the
+ * list or actually also free all cookies within the list as well.
+ *
  ****************************************************************************/
 
-void Curl_cookie_freelist(struct Cookie *co)
+void Curl_cookie_freelist(struct Cookie *co, bool cookiestoo)
 {
   struct Cookie *next;
   while(co) {
     next = co->next;
-    freecookie(co);
+    if(cookiestoo)
+      freecookie(co);
+    else
+      free(co); /* we only free the struct since the "members" are all just
+                   pointed out in the main cookie list! */
     co = next;
   }
 }
@@ -1289,7 +1232,7 @@ void Curl_cookie_cleanup(struct CookieInfo *c)
 {
   if(c) {
     free(c->filename);
-    Curl_cookie_freelist(c->cookies);
+    Curl_cookie_freelist(c->cookies, TRUE);
     free(c); /* free the base struct as well */
   }
 }
@@ -1347,7 +1290,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
   /* at first, remove expired cookies */
   remove_expired(c);
 
-  if(!strcmp("-", dumphere)) {
+  if(strequal("-", dumphere)) {
     /* use stdout */
     out = stdout;
     use_stdout=TRUE;