From: Stefan Eissing Date: Wed, 12 Mar 2025 10:31:21 +0000 (+0100) Subject: sendf: client reader line conversion: do not change data->state.infilesize X-Git-Tag: curl-8_13_0~166 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=3c9a1d3fcf14442a6a71651e3bd49a580abdd8fe;p=thirdparty%2Fcurl.git sendf: client reader line conversion: do not change data->state.infilesize 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 --- diff --git a/lib/ftp.c b/lib/ftp.c index 722dce41a3..b13d4c0a3f 100644 --- 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); diff --git a/lib/sendf.c b/lib/sendf.c index 54d3f56ce3..59da44b270 100644 --- a/lib/sendf.c +++ b/lib/sendf.c @@ -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,