mirror of https://github.com/moparisthebest/curl
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
This commit is contained in:
parent
bc64377ff8
commit
0044443a02
|
@ -161,7 +161,7 @@ static CURLcode altsvc_add(struct altsvcinfo *asi, char *line)
|
||||||
date, &persist, &prio);
|
date, &persist, &prio);
|
||||||
if(9 == rc) {
|
if(9 == rc) {
|
||||||
struct altsvc *as;
|
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);
|
as = altsvc_create(srchost, dsthost, srcalpn, dstalpn, srcport, dstport);
|
||||||
if(as) {
|
if(as) {
|
||||||
as->expires = expires;
|
as->expires = expires;
|
||||||
|
|
|
@ -96,6 +96,7 @@ Example set of cookies:
|
||||||
#include "curl_get_line.h"
|
#include "curl_get_line.h"
|
||||||
#include "curl_memrchr.h"
|
#include "curl_memrchr.h"
|
||||||
#include "inet_pton.h"
|
#include "inet_pton.h"
|
||||||
|
#include "parsedate.h"
|
||||||
|
|
||||||
/* The last 3 #include files should be in this order */
|
/* The last 3 #include files should be in this order */
|
||||||
#include "curl_printf.h"
|
#include "curl_printf.h"
|
||||||
|
@ -715,7 +716,7 @@ Curl_cookie_add(struct Curl_easy *data,
|
||||||
else if(co->expirestr) {
|
else if(co->expirestr) {
|
||||||
/* Note that if the date couldn't get parsed for whatever reason,
|
/* Note that if the date couldn't get parsed for whatever reason,
|
||||||
the cookie will be treated as a session cookie */
|
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
|
/* 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
|
from the date parser let's add a second to make it a
|
||||||
|
|
|
@ -2039,13 +2039,11 @@ static CURLcode ftp_state_mdtm_resp(struct connectdata *conn,
|
||||||
&year, &month, &day, &hour, &minute, &second)) {
|
&year, &month, &day, &hour, &minute, &second)) {
|
||||||
/* we have a time, reformat it */
|
/* we have a time, reformat it */
|
||||||
char timebuf[24];
|
char timebuf[24];
|
||||||
time_t secs = time(NULL);
|
|
||||||
|
|
||||||
msnprintf(timebuf, sizeof(timebuf),
|
msnprintf(timebuf, sizeof(timebuf),
|
||||||
"%04d%02d%02d %02d:%02d:%02d GMT",
|
"%04d%02d%02d %02d:%02d:%02d GMT",
|
||||||
year, month, day, hour, minute, second);
|
year, month, day, hour, minute, second);
|
||||||
/* now, convert this into a time() value: */
|
/* 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
|
#ifdef CURL_FTP_HTTPSTYLE_HEAD
|
||||||
|
|
|
@ -3974,7 +3974,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||||
else if(checkprefix("Retry-After:", k->p)) {
|
else if(checkprefix("Retry-After:", k->p)) {
|
||||||
/* Retry-After = HTTP-date / delay-seconds */
|
/* Retry-After = HTTP-date / delay-seconds */
|
||||||
curl_off_t retry_after = 0; /* zero for unknown or "now" */
|
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) {
|
if(-1 == date) {
|
||||||
/* not a date, try it as a decimal number */
|
/* not a date, try it as a decimal number */
|
||||||
(void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
|
(void)curlx_strtoofft(&k->p[12], NULL, 10, &retry_after);
|
||||||
|
@ -4032,9 +4032,7 @@ CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||||
#endif
|
#endif
|
||||||
else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
|
else if(!k->http_bodyless && checkprefix("Last-Modified:", k->p) &&
|
||||||
(data->set.timecondition || data->set.get_filetime) ) {
|
(data->set.timecondition || data->set.get_filetime) ) {
|
||||||
time_t secs = time(NULL);
|
k->timeofdoc = Curl_getdate_capped(k->p + strlen("Last-Modified:"));
|
||||||
k->timeofdoc = curl_getdate(k->p + strlen("Last-Modified:"),
|
|
||||||
&secs);
|
|
||||||
if(data->set.get_filetime)
|
if(data->set.get_filetime)
|
||||||
data->info.filetime = k->timeofdoc;
|
data->info.filetime = k->timeofdoc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -587,6 +587,30 @@ time_t curl_getdate(const char *p, const time_t *now)
|
||||||
return -1;
|
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
|
* Curl_gmtime() is a gmtime() replacement for portability. Do not use the
|
||||||
* gmtime_r() or gmtime() functions anywhere else but here.
|
* gmtime_r() or gmtime() functions anywhere else but here.
|
||||||
|
|
|
@ -27,4 +27,10 @@ extern const char * const Curl_month[12];
|
||||||
|
|
||||||
CURLcode Curl_gmtime(time_t intime, struct tm *store);
|
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 */
|
#endif /* HEADER_CURL_PARSEDATE_H */
|
||||||
|
|
Loading…
Reference in New Issue