]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
parsedate: offer a getdate_capped() alternative
authorDaniel Stenberg <daniel@haxx.se>
Thu, 28 Nov 2019 14:27:58 +0000 (15:27 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 29 Nov 2019 10:01:24 +0000 (11:01 +0100)
... and use internally. This function will return TIME_T_MAX instead of
failure if the parsed data is found to be larger than what can be
represented. TIME_T_MAX being the largest value curl can represent.

Reviewed-by: Daniel Gustafsson
Reported-by: JanB on github
Fixes #4152
Closes #4651

lib/altsvc.c
lib/cookie.c
lib/ftp.c
lib/http.c
lib/parsedate.c
lib/parsedate.h

index c3dbb708ae7ad4dd7f641f605717eaed18b66f4a..28c9276b1b45acebd6c8ffa1b72bd468eabca6d7 100644 (file)
@@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
               date, &persist, &prio);
   if(9 == rc) {
     struct altsvc *as;
-    time_t expires = curl_getdate(date, NULL);
+    time_t expires = Curl_getdate_capped(date);
     as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
     if(as) {
       as->expires = expires;
index 7e68b0785cd4eb2a2bf5a9cb29c19cffc0a49ab3..c9e420ad4b3404405e4278b946cc98d9b7c78cf6 100644 (file)
@@ -96,6 +96,7 @@ Example set of cookies:
 #include "curl_get_line.h"
 #include "curl_memrchr.h"
 #include "inet_pton.h"
+#include "parsedate.h"
 
 /* The last 3 #include files should be in this order */
 #include "curl_printf.h"
@@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
     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);
+      co->expires = Curl_getdate_capped(co->expirestr);
 
       /* 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
index 8072a33d5deadf9f1a275c56a2e7194486ba69b2..469096f0f69e1f45196ac77e21342000437a058e 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
                      &year, &month, &day, &hour, &minute, &second)) {
         /* we have a time, reformat it */
         char timebuf[24];
-        time_t secs = time(NULL);
-
         msnprintf(timebuf, sizeof(timebuf),
                   "%04d%02d%02d %02d:%02d:%02d GMT",
                   year, month, day, hour, minute, second);
         /* now, convert this into a time() value: */
-        data->info.filetime = curl_getdate(timebuf, &secs);
+        data->info.filetime = Curl_getdate_capped(timebuf);
       }
 
 #ifdef CURL_FTP_HTTPSTYLE_HEAD
index e344663d0679c4dde3b33a051aa69c19880b3e42..8857045605a0bcf393d816d07ae3fc91e893f5eb 100644 (file)
@@ -3974,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
     else if(checkprefix("Retry-After:", k->p)) {
       /* Retry-After = HTTP-date / delay-seconds */
       curl_off_t retry_after = 0; /* zero for unknown or "now" */
-      time_t date = curl_getdate(&k->p[12], NULL);
+      time_t date = Curl_getdate_capped(&k->p[12]);
       if(-1 == date) {
         /* not a date, try it as a decimal number */
         (void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
@@ -4032,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
 #endif
     else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
             (data->set.timecondition || data->set.get_filetime) ) {
-      time_t secs = time(NULL);
-      k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
-                                  &secs);
+      k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:"));
       if(data->set.get_filetime)
         data->info.filetime = k->timeofdoc;
     }
index f4b18d091acf0dad1dc977be36f07741dfb4d7ec..585d7ea404de389c588e597ef9ef1f068ef5bc9a 100644 (file)
@@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now)
   return -1;
 }
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p)
+{
+  time_t parsed = -1;
+  int rc = parsedate(p, &parsed);
+
+  switch(rc) {
+  case PARSEDATE_OK:
+    if(parsed == -1)
+      /* avoid returning -1 for a working scenario */
+      parsed++;
+    return parsed;
+  case PARSEDATE_LATER:
+    /* this returns the maximum time value */
+    return parsed;
+  default:
+    return -1; /* everything else is fail */
+  }
+  /* UNREACHABLE */
+}
+
 /*
  * Curl_gmtime() is a gmtime() replacement for portability. Do not use the
  * gmtime_r() or gmtime() functions anywhere else but here.
index 83d4c1f2400bf315b8e450f28c5dc9ae6f911486..8c7ae94e43870d6b448ea194da09a9a441b576e6 100644 (file)
@@ -27,4 +27,10 @@ extern const char * const Curl_month[12];
 
 CURLcode Curl_gmtime(time_t intime, struct tm *store);
 
+/* Curl_getdate_capped() differs from curl_getdate() in that this will return
+   TIME_T_MAX in case the parsed time value was too big, instead of an
+   error. */
+
+time_t Curl_getdate_capped(const char *p);
+
 #endif /* HEADER_CURL_PARSEDATE_H */