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
This commit is contained in:
Daniel Stenberg 2022-10-13 11:30:16 +02:00
Родитель b0e4ebe960
Коммит b46136f9b1
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 5CC908FDB71E12C2
1 изменённых файлов: 8 добавлений и 8 удалений

Просмотреть файл

@ -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)) {