Commit ecaf2f02 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

cookie: max-age fixes

1 - allow >31 bit max-age values

2 - don't overflow on extremely large max-age values when we add the
value to the current time

3 - make sure max-age takes precedence over expires as dictated by
RFC6265

Bug: http://curl.haxx.se/mail/lib-2014-01/0130.html
Reported-by: Chen Prog
parent d4296f6f
Loading
Loading
Loading
Loading
+24 −14
Original line number Original line Diff line number Diff line
@@ -489,9 +489,6 @@ Curl_cookie_add(struct SessionHandle *data,
            badcookie = TRUE;
            badcookie = TRUE;
            break;
            break;
          }
          }
          co->expires =
            strtol((*co->maxage=='\"')?&co->maxage[1]:&co->maxage[0],NULL,10)
            + (long)now;
        }
        }
        else if(Curl_raw_equal("expires", name)) {
        else if(Curl_raw_equal("expires", name)) {
          strstore(&co->expirestr, whatptr);
          strstore(&co->expirestr, whatptr);
@@ -499,17 +496,6 @@ Curl_cookie_add(struct SessionHandle *data,
            badcookie = TRUE;
            badcookie = TRUE;
            break;
            break;
          }
          }
          /* Note that if the date couldn't get parsed for whatever reason,
             the cookie will be treated as a session cookie */
          co->expires = curl_getdate(what, NULL);

          /* Session cookies have expires set to 0 so if we get that back
             from the date parser let's add a second to make it a
             non-session cookie */
          if(co->expires == 0)
            co->expires = 1;
          else if(co->expires < 0)
            co->expires = 0;
        }
        }
        else if(!co->name) {
        else if(!co->name) {
          co->name = strdup(name);
          co->name = strdup(name);
@@ -544,6 +530,30 @@ Curl_cookie_add(struct SessionHandle *data,
        semiptr=strchr(ptr, '\0');
        semiptr=strchr(ptr, '\0');
    } while(semiptr);
    } while(semiptr);


    if(co->maxage) {
      co->expires =
        curlx_strtoofft((*co->maxage=='\"')?
                        &co->maxage[1]:&co->maxage[0], NULL, 10);
      if(CURL_OFF_T_MAX - now < co->expires)
        /* avoid overflow */
        co->expires = CURL_OFF_T_MAX;
      else
        co->expires += now;
    }
    else if(co->expirestr) {
      /* Note that if the date couldn't get parsed for whatever reason,
         the cookie will be treated as a session cookie */
      co->expires = curl_getdate(co->expirestr, NULL);

      /* Session cookies have expires set to 0 so if we get that back
         from the date parser let's add a second to make it a
         non-session cookie */
      if(co->expires == 0)
        co->expires = 1;
      else if(co->expires < 0)
        co->expires = 0;
    }

    if(!badcookie && !co->domain) {
    if(!badcookie && !co->domain) {
      if(domain) {
      if(domain) {
        /* no domain was given in the header line, set the default */
        /* no domain was given in the header line, set the default */