Skip to content

Commit 0044443

Browse files
committed
parsedate: offer a getdate_capped() alternative
... 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
1 parent bc64377 commit 0044443

File tree

6 files changed

+36
-9
lines changed

6 files changed

+36
-9
lines changed

lib/altsvc.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
161161
date, &persist, &prio);
162162
if(9 == rc) {
163163
struct altsvc *as;
164-
time_t expires = curl_getdate(date, NULL);
164+
time_t expires = Curl_getdate_capped(date);
165165
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
166166
if(as) {
167167
as->expires = expires;

lib/cookie.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ Example set of cookies:
9696
#include "curl_get_line.h"
9797
#include "curl_memrchr.h"
9898
#include "inet_pton.h"
99+
#include "parsedate.h"
99100

100101
/* The last 3 #include files should be in this order */
101102
#include "curl_printf.h"
@@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
715716
else if(co->expirestr) {
716717
/* Note that if the date couldn't get parsed for whatever reason,
717718
the cookie will be treated as a session cookie */
718-
co->expires = curl_getdate(co->expirestr, NULL);
719+
co->expires = Curl_getdate_capped(co->expirestr);
719720

720721
/* Session cookies have expires set to 0 so if we get that back
721722
from the date parser let's add a second to make it a

lib/ftp.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
20392039
&year, &month, &day, &hour, &minute, &second)) {
20402040
/* we have a time, reformat it */
20412041
char timebuf[24];
2042-
time_t secs = time(NULL);
2043-
20442042
msnprintf(timebuf, sizeof(timebuf),
20452043
"%04d%02d%02d %02d:%02d:%02d GMT",
20462044
year, month, day, hour, minute, second);
20472045
/* now, convert this into a time() value: */
2048-
data->info.filetime = curl_getdate(timebuf, &secs);
2046+
data->info.filetime = Curl_getdate_capped(timebuf);
20492047
}
20502048

20512049
#ifdef CURL_FTP_HTTPSTYLE_HEAD

lib/http.c

+2-4
Original file line numberDiff line numberDiff line change
@@ -3974,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
39743974
else if(checkprefix("Retry-After:", k->p)) {
39753975
/* Retry-After = HTTP-date / delay-seconds */
39763976
curl_off_t retry_after = 0; /* zero for unknown or "now" */
3977-
time_t date = curl_getdate(&k->p[12], NULL);
3977+
time_t date = Curl_getdate_capped(&k->p[12]);
39783978
if(-1 == date) {
39793979
/* not a date, try it as a decimal number */
39803980
(void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
@@ -4032,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
40324032
#endif
40334033
else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
40344034
(data->set.timecondition || data->set.get_filetime) ) {
4035-
time_t secs = time(NULL);
4036-
k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
4037-
&secs);
4035+
k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:"));
40384036
if(data->set.get_filetime)
40394037
data->info.filetime = k->timeofdoc;
40404038
}

lib/parsedate.c

+24
Original file line numberDiff line numberDiff line change
@@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now)
587587
return -1;
588588
}
589589

590+
/* Curl_getdate_capped() differs from curl_getdate() in that this will return
591+
TIME_T_MAX in case the parsed time value was too big, instead of an
592+
error. */
593+
594+
time_t Curl_getdate_capped(const char *p)
595+
{
596+
time_t parsed = -1;
597+
int rc = parsedate(p, &parsed);
598+
599+
switch(rc) {
600+
case PARSEDATE_OK:
601+
if(parsed == -1)
602+
/* avoid returning -1 for a working scenario */
603+
parsed++;
604+
return parsed;
605+
case PARSEDATE_LATER:
606+
/* this returns the maximum time value */
607+
return parsed;
608+
default:
609+
return -1; /* everything else is fail */
610+
}
611+
/* UNREACHABLE */
612+
}
613+
590614
/*
591615
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the
592616
* gmtime_r() or gmtime() functions anywhere else but here.

lib/parsedate.h

+6
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,10 @@ extern const char * const Curl_month[12];
2727

2828
CURLcode Curl_gmtime(time_t intime, struct tm *store);
2929

30+
/* Curl_getdate_capped() differs from curl_getdate() in that this will return
31+
TIME_T_MAX in case the parsed time value was too big, instead of an
32+
error. */
33+
34+
time_t Curl_getdate_capped(const char *p);
35+
3036
#endif /* HEADER_CURL_PARSEDATE_H */

0 commit comments

Comments
 (0)