]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
sendf: client reader line conversion: do not change data->state.infilesize
authorStefan Eissing <stefan@eissing.org>
Wed, 12 Mar 2025 10:31:21 +0000 (11:31 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Wed, 12 Mar 2025 13:33:28 +0000 (14:33 +0100)
The line conversion reader, added in crfl and prefer_ascii mode was
incrementing data->state.infilesize for every line end converted. This
results in the wrong size to start a retry of an upload.

Eliminate the increment and check upload size in FTP less precise when
conversions are done.

Bug: https://issues.oss-fuzz.com/issues/402476456

Closes #16683

lib/ftp.c
lib/sendf.c

index 722dce41a326ee6ff43b07cbf2d43cb49fc3514d..b13d4c0a3fee5038fb6666bc2ab458f5db2fe5ab 100644 (file)
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -3371,10 +3371,13 @@ static CURLcode ftp_done(struct Curl_easy *data, CURLcode status,
        use checking further */
     ;
   else if(data->state.upload) {
-    if((-1 != data->state.infilesize) &&
-       (data->state.infilesize != data->req.writebytecount) &&
-       !data->set.crlf &&
-       (ftp->transfer == PPTRANSFER_BODY)) {
+    if((ftp->transfer == PPTRANSFER_BODY) &&
+       (data->state.infilesize != -1) && /* upload with known size */
+       ((!data->set.crlf && !data->state.prefer_ascii && /* no conversion */
+         (data->state.infilesize != data->req.writebytecount)) ||
+        ((data->set.crlf || data->state.prefer_ascii) && /* maybe crlf conv */
+         (data->state.infilesize > data->req.writebytecount))
+       )) {
       failf(data, "Uploaded unaligned file size (%" FMT_OFF_T
             " out of %" FMT_OFF_T " bytes)",
             data->req.writebytecount, data->state.infilesize);
index 54d3f56ce3d007ca56c39890dacec0508509bd4b..59da44b2706f6b46c54f76fa6678a692bb56c452 100644 (file)
@@ -1030,13 +1030,6 @@ static CURLcode cr_lc_read(struct Curl_easy *data,
       if(result)
         return result;
       start = i + 1;
-      if(!data->set.crlf && (data->state.infilesize != -1)) {
-        /* we are here only because FTP is in ASCII mode...
-           bump infilesize for the LF we just added */
-        data->state.infilesize++;
-        /* comment: this might work for FTP, but in HTTP we could not change
-         * the content length after having started the request... */
-      }
     }
 
     if(start < i) { /* leftover */
@@ -1313,6 +1306,15 @@ static bool cr_buf_needs_rewind(struct Curl_easy *data,
   return ctx->index > 0;
 }
 
+static CURLcode cr_buf_rewind(struct Curl_easy *data,
+                              struct Curl_creader *reader)
+{
+  struct cr_buf_ctx *ctx = reader->ctx;
+  (void)data;
+  ctx->index = 0;
+  return CURLE_OK;
+}
+
 static curl_off_t cr_buf_total_length(struct Curl_easy *data,
                                       struct Curl_creader *reader)
 {
@@ -1352,7 +1354,7 @@ static const struct Curl_crtype cr_buf = {
   cr_buf_needs_rewind,
   cr_buf_total_length,
   cr_buf_resume_from,
-  Curl_creader_def_rewind,
+  cr_buf_rewind,
   Curl_creader_def_unpause,
   Curl_creader_def_is_paused,
   Curl_creader_def_done,