diff options
author | Daniel Stenberg <daniel@haxx.se> | 2022-10-13 11:30:16 +0200 |
---|---|---|
committer | Daniel Stenberg <daniel@haxx.se> | 2022-10-13 17:27:08 +0200 |
commit | b46136f9b14dbc4ed00cc92b189eaacd991a2c9f (patch) | |
tree | 550d676db347cc2f23493c601a6d399513fb74a9 /lib/http.c | |
parent | b0e4ebe9605d8fbddcd6fc0d9d2593c1b2f818d9 (diff) | |
download | curl-b46136f9b14dbc4ed00cc92b189eaacd991a2c9f.tar.gz |
http: try parsing Retry-After: as a number first
Since the date parser allows YYYYMMDD as a date format (due to it being
a bit too generic for parsing this particular header), a large integer
number could wrongly match that pattern and cause the parser to generate
a wrong value.
No date format accepted for this header starts with a decimal number, so
by reversing the check and trying a number first we can deduct that if
that works, it was not a date.
Reported-by Trail of Bits
Closes #9718
Diffstat (limited to 'lib/http.c')
-rw-r--r-- | lib/http.c | 16 |
1 files changed, 8 insertions, 8 deletions
diff --git a/lib/http.c b/lib/http.c index 531c6daf8..8801f91a4 100644 --- a/lib/http.c +++ b/lib/http.c @@ -3583,15 +3583,15 @@ CURLcode Curl_http_header(struct Curl_easy *data, struct connectdata *conn, else if(checkprefix("Retry-After:", headp)) { /* Retry-After = HTTP-date / delay-seconds */ curl_off_t retry_after = 0; /* zero for unknown or "now" */ - time_t date = Curl_getdate_capped(headp + strlen("Retry-After:")); - if(-1 == date) { - /* not a date, try it as a decimal number */ - (void)curlx_strtoofft(headp + strlen("Retry-After:"), - NULL, 10, &retry_after); + /* Try it as a decimal number, if it works it is not a date */ + (void)curlx_strtoofft(headp + strlen("Retry-After:"), + NULL, 10, &retry_after); + if(!retry_after) { + time_t date = Curl_getdate_capped(headp + strlen("Retry-After:")); + if(-1 != date) + /* convert date to number of seconds into the future */ + retry_after = date - time(NULL); } - else - /* convert date to number of seconds into the future */ - retry_after = date - time(NULL); data->info.retry_after = retry_after; /* store it */ } else if(!k->http_bodyless && checkprefix("Content-Range:", headp)) { |