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
This commit is contained in:
Stefan Eissing 2025-03-12 11:31:21 +01:00 committed by Daniel Stenberg
parent fdd97148e8
commit 3c9a1d3fcf
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
2 changed files with 17 additions and 12 deletions

View File

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

View 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,