]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
http: try parsing Retry-After: as a number first
authorDaniel Stenberg <daniel@haxx.se>
Thu, 13 Oct 2022 09:30:16 +0000 (11:30 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 13 Oct 2022 15:27:08 +0000 (17:27 +0200)
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

lib/http.c

index 531c6daf87407cb14573e5295f59fea7db0e5069..8801f91a489aca73604423a240cc0cbd12ccbbb4 100644 (file)
@@ -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)) {