parsedate: make Curl_getdate_capped able to return epoch
No binary (build failed)
—
(log yok)
| @@ -187,13 +187,13 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, const char *line) | |
| else { | |
| struct altsvc *as; | |
| char dbuf[MAX_ALTSVC_DATELEN + 1]; | |
| - | time_t expires; |
| + | time_t expires = 0; |
| /* The date parser works on a null-terminated string. The maximum length | |
| is upheld by curlx_str_quotedword(). */ | |
| memcpy(dbuf, curlx_str(&date), curlx_strlen(&date)); | |
| dbuf[curlx_strlen(&date)] = 0; | |
| - | expires = Curl_getdate_capped(dbuf); |
| + | Curl_getdate_capped(dbuf, &expires); |
| as = altsvc_create(&srchost, &dsthost, &srcalpn, &dstalpn, | |
| (size_t)srcport, (size_t)dstport); | |
| if(as) { | |
| @@ -107,7 +107,7 @@ static void strstore(char **str, const char *newstr, size_t len); | |
| */ | |
| static void cap_expires(time_t now, struct Cookie *co) | |
| { | |
| - | if((TIME_T_MAX - COOKIES_MAXAGE - 30) > now) { |
| + | if(co->expires && (TIME_T_MAX - COOKIES_MAXAGE - 30) > now) { |
| timediff_t cap = now + COOKIES_MAXAGE; | |
| if(co->expires > cap) { | |
| cap += 30; | |
| @@ -388,17 +388,17 @@ static void remove_expired(struct CookieInfo *ci) | |
| for(n = Curl_llist_head(&ci->cookielist[i]); n; n = e) { | |
| co = Curl_node_elem(n); | |
| e = Curl_node_next(n); | |
| - | if(co->expires && co->expires < now) { |
| - | Curl_node_remove(n); |
| - | freecookie(co); |
| - | ci->numcookies--; |
| - | } |
| - | else { |
| - | /* |
| - | * If this cookie has an expiration timestamp earlier than what we |
| - | * have seen so far then record it for the next round of expirations. |
| - | */ |
| - | if(co->expires && co->expires < ci->next_expiration) |
| + | if(co->expires) { |
| + | if(co->expires < now) { |
| + | Curl_node_remove(n); |
| + | freecookie(co); |
| + | ci->numcookies--; |
| + | } |
| + | else if(co->expires < ci->next_expiration) |
| + | /* |
| + | * If this cookie has an expiration timestamp earlier than what we |
| + | * have seen so far then record it for the next round of expirations. |
| + | */ |
| ci->next_expiration = co->expires; | |
| } | |
| } | |
| @@ -666,7 +666,6 @@ parse_cookie_header(struct Curl_easy *data, | |
| if(*maxage == '\"') | |
| maxage++; | |
| rc = curlx_str_number(&maxage, &co->expires, CURL_OFF_T_MAX); | |
| - | |
| switch(rc) { | |
| case STRE_OVERFLOW: | |
| /* overflow, used max value */ | |
| @@ -678,8 +677,7 @@ parse_cookie_header(struct Curl_easy *data, | |
| break; | |
| case STRE_OK: | |
| if(!co->expires) | |
| - | /* already expired */ |
| - | co->expires = 1; |
| + | co->expires = 1; /* expire now */ |
| else if(CURL_OFF_T_MAX - now < co->expires) | |
| /* would overflow */ | |
| co->expires = CURL_OFF_T_MAX; | |
| @@ -698,18 +696,15 @@ parse_cookie_header(struct Curl_easy *data, | |
| * will be treated as a session cookie | |
| */ | |
| char dbuf[MAX_DATE_LENGTH + 1]; | |
| + | time_t date = 0; |
| memcpy(dbuf, curlx_str(&val), curlx_strlen(&val)); | |
| dbuf[curlx_strlen(&val)] = 0; | |
| - | co->expires = Curl_getdate_capped(dbuf); |
| - | |
| - | /* |
| - | * 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) |
| + | if(!Curl_getdate_capped(dbuf, &date)) { |
| + | if(!date) |
| + | date++; |
| + | co->expires = (curl_off_t)date; |
| + | } |
| + | else |
| co->expires = 0; | |
| cap_expires(now, co); | |
| } | |
| @@ -1103,7 +1098,7 @@ Curl_cookie_add(struct Curl_easy *data, | |
| if(!ci->running && /* read from a file */ | |
| ci->newsession && /* clean session cookies */ | |
| - | !co->expires) /* this is a session cookie since it does not expire */ |
| + | !co->expires) /* this is a session cookie */ |
| goto fail; | |
| co->livecookie = ci->running; | |
| @@ -2102,6 +2102,7 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, | |
| int year, month, day, hour, minute, second; | |
| struct pingpong *pp = &ftpc->pp; | |
| char *resp = curlx_dyn_ptr(&pp->recvbuf) + 4; | |
| + | bool showtime = FALSE; |
| if(ftp_213_date(resp, &year, &month, &day, &hour, &minute, &second)) { | |
| /* we have a time, reformat it */ | |
| char timebuf[24]; | |
| @@ -2109,7 +2110,8 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, | |
| "%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_capped(timebuf); |
| + | if(!Curl_getdate_capped(timebuf, &data->info.filetime)) |
| + | showtime = TRUE; |
| } | |
| #ifdef CURL_FTP_HTTPSTYLE_HEAD | |
| @@ -2122,10 +2124,8 @@ static CURLcode ftp_state_mdtm_resp(struct Curl_easy *data, | |
| warning: comparison of unsigned expression in '>= 0' is always true */ | |
| #pragma GCC diagnostic ignored "-Wtype-limits" | |
| #endif | |
| - | if(data->req.no_body && |
| - | ftpc->file && |
| - | data->set.get_filetime && |
| - | (data->info.filetime >= 0) ) { |
| + | if(data->req.no_body && ftpc->file && |
| + | data->set.get_filetime && showtime) { |
| #if defined(__GNUC__) && (defined(__DJGPP__) || defined(__AMIGA__)) | |
| #pragma GCC diagnostic pop | |
| #endif | |
| @@ -426,7 +426,7 @@ static CURLcode hsts_add(struct hsts *h, const char *line) | |
| bool subdomain = FALSE; | |
| struct stsentry *e; | |
| char dbuf[MAX_HSTS_DATELEN + 1]; | |
| - | time_t expires; |
| + | time_t expires = 0; |
| const char *hp = curlx_str(&host); | |
| /* The date parser works on a null-terminated string. The maximum length | |
| @@ -434,8 +434,10 @@ static CURLcode hsts_add(struct hsts *h, const char *line) | |
| memcpy(dbuf, curlx_str(&date), curlx_strlen(&date)); | |
| dbuf[curlx_strlen(&date)] = 0; | |
| - | expires = strcmp(dbuf, UNLIMITED) ? Curl_getdate_capped(dbuf) : |
| - | TIME_T_MAX; |
| + | if(!strcmp(dbuf, UNLIMITED)) |
| + | expires = TIME_T_MAX; |
| + | else |
| + | Curl_getdate_capped(dbuf, &expires); |
| if(hp[0] == '.') { | |
| curlx_str_nudge(&host, 1); | |
| @@ -478,14 +480,14 @@ static CURLcode hsts_pull(struct Curl_easy *data, struct hsts *h) | |
| e.name[0] = 0; /* just to make it clean */ | |
| sc = data->set.hsts_read(data, &e, data->set.hsts_read_userp); | |
| if(sc == CURLSTS_OK) { | |
| - | time_t expires; |
| + | time_t expires = 0; |
| CURLcode result; | |
| DEBUGASSERT(e.name[0]); | |
| if(!e.name[0]) | |
| /* bail out if no name was stored */ | |
| return CURLE_BAD_FUNCTION_ARGUMENT; | |
| if(e.expire[0]) | |
| - | expires = Curl_getdate_capped(e.expire); |
| + | Curl_getdate_capped(e.expire, &expires); |
| else | |
| expires = TIME_T_MAX; /* the end of time */ | |
| result = hsts_create(h, e.name, strlen(e.name), | |
| @@ -3196,7 +3196,8 @@ static CURLcode http_header_l(struct Curl_easy *data, | |
| (data->set.timecondition || data->set.get_filetime)) ? | |
| HD_VAL(hd, hdlen, "Last-Modified:") : NULL; | |
| if(v) { | |
| - | k->timeofdoc = Curl_getdate_capped(v); |
| + | if(Curl_getdate_capped(v, &k->timeofdoc)) |
| + | k->timeofdoc = 0; |
| if(data->set.get_filetime) | |
| data->info.filetime = k->timeofdoc; | |
| return CURLE_OK; | |
| @@ -3311,14 +3312,12 @@ static CURLcode http_header_r(struct Curl_easy *data, | |
| if(v) { | |
| /* Retry-After = HTTP-date / delay-seconds */ | |
| curl_off_t retry_after = 0; /* zero for unknown or "now" */ | |
| - | time_t date; |
| + | time_t date = 0; |
| curlx_str_passblanks(&v); | |
| /* try it as a date first, because a date can otherwise start with and | |
| get treated as a number */ | |
| - | date = Curl_getdate_capped(v); |
| - | |
| - | if((time_t)-1 != date) { |
| + | if(!Curl_getdate_capped(v, &date)) { |
| time_t current = time(NULL); | |
| if(date >= current) | |
| /* convert date to number of seconds into the future */ | |
| @@ -589,26 +589,12 @@ time_t curl_getdate(const char *p, const time_t *now) | |
| /* 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. */ |
| + | error. Returns non-zero on error. */ |
| - | time_t Curl_getdate_capped(const char *p) |
| + | int Curl_getdate_capped(const char *p, time_t *tp) |
| { | |
| - | time_t parsed = -1; |
| - | int rc = parsedate(p, &parsed); |
| - | |
| - | switch(rc) { |
| - | case PARSEDATE_OK: |
| - | if(parsed == (time_t)-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 */ |
| + | int rc = parsedate(p, tp); |
| + | return (rc == PARSEDATE_FAIL); |
| } | |
| /* | |
| @@ -29,10 +29,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 |
| + | /* Curl_getdate_capped() differs from curl_getdate() in that this returns |
| TIME_T_MAX in case the parsed time value was too big, instead of an | |
| error. */ | |
| - | time_t Curl_getdate_capped(const char *p); |
| + | int Curl_getdate_capped(const char *p, time_t *store); |
| #endif /* HEADER_CURL_PARSEDATE_H */ | |
| @@ -1855,9 +1855,9 @@ static int myssh_in_SFTP_QUOTE_STAT(struct Curl_easy *data, | |
| } | |
| else if(!strncmp(cmd, "atime", 5) || | |
| !strncmp(cmd, "mtime", 5)) { | |
| - | time_t date = Curl_getdate_capped(sshc->quote_path1); |
| + | time_t date; |
| bool fail = FALSE; | |
| - | if(date == -1) { |
| + | if(Curl_getdate_capped(sshc->quote_path1, &date)) { |
| failf(data, "incorrect date format for %.*s", 5, cmd); | |
| fail = TRUE; | |
| } | |
| @@ -1390,16 +1390,16 @@ sftp_quote_stat(struct Curl_easy *data, | |
| } | |
| else if(!strncmp(cmd, "atime", 5) || | |
| !strncmp(cmd, "mtime", 5)) { | |
| - | time_t date = Curl_getdate_capped(sshc->quote_path1); |
| + | time_t date; |
| bool fail = FALSE; | |
| - | if(date == -1) { |
| + | if(Curl_getdate_capped(sshc->quote_path1, &date)) { |
| failf(data, "incorrect date format for %.*s", 5, cmd); | |
| fail = TRUE; | |
| } | |
| #if SIZEOF_TIME_T > SIZEOF_LONG | |
| if(date > 0xffffffff) { | |
| - | /* if 'long' cannot old >32-bit, this date cannot be sent */ |
| + | /* if 'long' cannot hold >32-bit, this date cannot be sent */ |
| failf(data, "date overflow"); | |
| fail = TRUE; | |
| } | |