]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
ftp: simplify the 150/126 size scanner
authorDaniel Stenberg <daniel@haxx.se>
Thu, 9 Oct 2025 20:32:09 +0000 (22:32 +0200)
committerDaniel Stenberg <daniel@haxx.se>
Thu, 9 Oct 2025 21:26:30 +0000 (23:26 +0200)
The file size is weirdly returned in a 150 or 126 response as "XXX
bytes" mentioned somewhere in the response string. This is a rewrite of
the size scanner to replace the strange strstr() + backwards search from
before with a plain forward search until '[number] + " bytes"' is a
match.

Triggered by a report by Joshua Rogers about the previous parser.

Closes #18984

lib/ftp.c

index c3b8aafbc5d5691a276ba0c9c607f19209bc2332..adcad3dd7587942def8195e472bc602948321654 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -2496,30 +2496,19 @@ static CURLcode ftp_state_get_resp(struct Curl_easy *data,
        * those cases only confuses us.
        *
        * Example D above makes this parsing a little tricky */
-      const char *bytes;
-      char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
-      bytes = strstr(buf, " bytes");
-      if(bytes) {
-        long in = (long)(--bytes-buf);
-        /* this is a hint there is size information in there! ;-) */
-        while(--in) {
-          /* scan for the left parenthesis and break there */
-          if('(' == *bytes)
-            break;
-          /* skip only digits */
-          if(!ISDIGIT(*bytes)) {
-            bytes = NULL;
+      size_t len = curlx_dyn_len(&ftpc->pp.recvbuf);
+      if(len >= 7) { /* "1 bytes" is 7 characters */
+        size_t i;
+        for(i = 0; i < len - 7; i++) {
+          curl_off_t what;
+          char *buf = curlx_dyn_ptr(&ftpc->pp.recvbuf);
+          const char *c = &buf[i];
+          if(!curlx_str_number(&c, &what, CURL_OFF_T_MAX) &&
+             !curlx_str_single(&c, ' ') &&
+             !strncmp(c, "bytes", 5)) {
+            size = what;
             break;
           }
-          /* one more estep backwards */
-          bytes--;
-        }
-        /* if we have nothing but digits: */
-        if(bytes) {
-          ++bytes;
-          /* get the number! */
-          if(curlx_str_number(&bytes, &size, CURL_OFF_T_MAX))
-            size = 1;
         }
       }
     }