FTP: partly revert eeb7c12807
Since ASCII transfers on FTP means sending CRLF line endings, we should
still keep converting them to LF-only on platforms where text files
typically do not use CRLF.
This also DOES NOT convert existing CRLF line endings on ASCII uploads
but only does stand-alone LF => CRLF.
Regression from eeb7c12807 shipped in 8.10.0
Reported-by: finkjsc on github
Fixes #14873
Closes #14875
This commit is contained in:
parent
2b652b8634
commit
7eda757d99
11
lib/ftp.c
11
lib/ftp.c
@ -327,6 +327,7 @@ static void freedirs(struct ftp_conn *ftpc)
|
|||||||
Curl_safefree(ftpc->newhost);
|
Curl_safefree(ftpc->newhost);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CURL_PREFER_LF_LINEENDS
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* Lineend Conversions
|
* Lineend Conversions
|
||||||
@ -415,6 +416,7 @@ static const struct Curl_cwtype ftp_cw_lc = {
|
|||||||
sizeof(struct ftp_cw_lc_ctx)
|
sizeof(struct ftp_cw_lc_ctx)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* CURL_PREFER_LF_LINEENDS */
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
*
|
*
|
||||||
* AcceptServerConnect()
|
* AcceptServerConnect()
|
||||||
@ -4138,12 +4140,15 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done)
|
|||||||
CURLcode result = CURLE_OK;
|
CURLcode result = CURLE_OK;
|
||||||
struct connectdata *conn = data->conn;
|
struct connectdata *conn = data->conn;
|
||||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||||
/* FTP data may need conversion. */
|
|
||||||
struct Curl_cwriter *ftp_lc_writer;
|
|
||||||
|
|
||||||
*done = FALSE; /* default to false */
|
*done = FALSE; /* default to false */
|
||||||
ftpc->wait_data_conn = FALSE; /* default to no such wait */
|
ftpc->wait_data_conn = FALSE; /* default to no such wait */
|
||||||
|
|
||||||
|
#ifdef CURL_PREFER_LF_LINEENDS
|
||||||
|
{
|
||||||
|
/* FTP data may need conversion. */
|
||||||
|
struct Curl_cwriter *ftp_lc_writer;
|
||||||
|
|
||||||
result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc,
|
result = Curl_cwriter_create(&ftp_lc_writer, data, &ftp_cw_lc,
|
||||||
CURL_CW_CONTENT_DECODE);
|
CURL_CW_CONTENT_DECODE);
|
||||||
if(result)
|
if(result)
|
||||||
@ -4154,6 +4159,8 @@ static CURLcode ftp_do(struct Curl_easy *data, bool *done)
|
|||||||
Curl_cwriter_free(data, ftp_lc_writer);
|
Curl_cwriter_free(data, ftp_lc_writer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif /* CURL_PREFER_LF_LINEENDS */
|
||||||
|
|
||||||
if(data->state.wildcardmatch) {
|
if(data->state.wildcardmatch) {
|
||||||
result = wc_statemach(data);
|
result = wc_statemach(data);
|
||||||
|
|||||||
16
lib/sendf.c
16
lib/sendf.c
@ -949,6 +949,7 @@ struct cr_lc_ctx {
|
|||||||
struct bufq buf;
|
struct bufq buf;
|
||||||
BIT(read_eos); /* we read an EOS from the next reader */
|
BIT(read_eos); /* we read an EOS from the next reader */
|
||||||
BIT(eos); /* we have returned an EOS */
|
BIT(eos); /* we have returned an EOS */
|
||||||
|
BIT(prev_cr); /* the last byte was a CR */
|
||||||
};
|
};
|
||||||
|
|
||||||
static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader)
|
static CURLcode cr_lc_init(struct Curl_easy *data, struct Curl_creader *reader)
|
||||||
@ -1005,10 +1006,15 @@ static CURLcode cr_lc_read(struct Curl_easy *data,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* at least one \n needs conversion to '\r\n', place into ctx->buf */
|
/* at least one \n might need conversion to '\r\n', place into ctx->buf */
|
||||||
for(i = start = 0; i < nread; ++i) {
|
for(i = start = 0; i < nread; ++i) {
|
||||||
if(buf[i] != '\n')
|
/* if this byte is not an LF character, or if the preceding character is
|
||||||
|
a CR (meaning this already is a CRLF pair), go to next */
|
||||||
|
if((buf[i] != '\n') || ctx->prev_cr) {
|
||||||
|
ctx->prev_cr = (buf[i] == '\r');
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
ctx->prev_cr = false;
|
||||||
/* on a soft limit bufq, we do not need to check length */
|
/* on a soft limit bufq, we do not need to check length */
|
||||||
result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n);
|
result = Curl_bufq_cwrite(&ctx->buf, buf + start, i - start, &n);
|
||||||
if(!result)
|
if(!result)
|
||||||
@ -1101,7 +1107,11 @@ static CURLcode do_init_reader_stack(struct Curl_easy *data,
|
|||||||
clen = r->crt->total_length(data, r);
|
clen = r->crt->total_length(data, r);
|
||||||
/* if we do not have 0 length init, and crlf conversion is wanted,
|
/* if we do not have 0 length init, and crlf conversion is wanted,
|
||||||
* add the reader for it */
|
* add the reader for it */
|
||||||
if(clen && (data->set.crlf || data->state.prefer_ascii)) {
|
if(clen && (data->set.crlf
|
||||||
|
#ifdef CURL_PREFER_LF_LINEENDS
|
||||||
|
|| data->state.prefer_ascii
|
||||||
|
#endif
|
||||||
|
)) {
|
||||||
result = cr_lc_add(data);
|
result = cr_lc_add(data);
|
||||||
if(result)
|
if(result)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@ -105,6 +105,12 @@ typedef unsigned int curl_prot_t;
|
|||||||
#define CURL_DEFAULT_USER "anonymous"
|
#define CURL_DEFAULT_USER "anonymous"
|
||||||
#define CURL_DEFAULT_PASSWORD "ftp@example.com"
|
#define CURL_DEFAULT_PASSWORD "ftp@example.com"
|
||||||
|
|
||||||
|
#if !defined(_WIN32) && !defined(MSDOS) && !defined(__EMX__)
|
||||||
|
/* do FTP line-end CRLF => LF conversions on platforms that prefer LF-only. It
|
||||||
|
also means: keep CRLF line endings on the CRLF platforms */
|
||||||
|
#define CURL_PREFER_LF_LINEENDS
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Convenience defines for checking protocols or their SSL based version. Each
|
/* Convenience defines for checking protocols or their SSL based version. Each
|
||||||
protocol handler should only ever have a single CURLPROTO_ in its protocol
|
protocol handler should only ever have a single CURLPROTO_ in its protocol
|
||||||
field. */
|
field. */
|
||||||
|
|||||||
@ -694,11 +694,14 @@ content
|
|||||||
|
|
||||||
### `<stripfile4>`
|
### `<stripfile4>`
|
||||||
|
|
||||||
### `<upload [crlf="yes"]>`
|
### `<upload [crlf="yes"] [nonewline="yes"]>`
|
||||||
the contents of the upload data curl should have sent
|
the contents of the upload data curl should have sent
|
||||||
|
|
||||||
`crlf=yes` forces *upload* newlines to become CRLF even if not written so in
|
`crlf=yes` forces *upload* newlines to become CRLF even if not written so in
|
||||||
the source file.
|
the source file.
|
||||||
|
|
||||||
|
`nonewline=yes` means that the last byte (the trailing newline character)
|
||||||
|
should be cut off from the upload data before comparing it.
|
||||||
|
|
||||||
### `<valgrind>`
|
### `<valgrind>`
|
||||||
disable - disables the valgrind log check for this test
|
disable - disables the valgrind log check for this test
|
||||||
|
|||||||
@ -16,8 +16,12 @@ ftp
|
|||||||
<name>
|
<name>
|
||||||
FTP PASV upload ASCII file
|
FTP PASV upload ASCII file
|
||||||
</name>
|
</name>
|
||||||
<file name="%LOGDIR/test%TESTNUMBER.txt">
|
<file name="%LOGDIR/test%TESTNUMBER.txt" nonewline="yes">
|
||||||
|
%if win32
|
||||||
|
%repeat[1750 x a line of text used for verifying this !%0d%0a]%
|
||||||
|
%else
|
||||||
%repeat[1750 x a line of text used for verifying this !%0a]%
|
%repeat[1750 x a line of text used for verifying this !%0a]%
|
||||||
|
%endif
|
||||||
</file>
|
</file>
|
||||||
<command>
|
<command>
|
||||||
"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt
|
"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt
|
||||||
@ -29,7 +33,7 @@ FTP PASV upload ASCII file
|
|||||||
<strip>
|
<strip>
|
||||||
QUIT
|
QUIT
|
||||||
</strip>
|
</strip>
|
||||||
<upload crlf="yes">
|
<upload crlf="yes" nonewline="yes">
|
||||||
%repeat[1750 x a line of text used for verifying this !%0a]%
|
%repeat[1750 x a line of text used for verifying this !%0a]%
|
||||||
</upload>
|
</upload>
|
||||||
<protocol>
|
<protocol>
|
||||||
|
|||||||
@ -16,8 +16,8 @@ ftp
|
|||||||
<name>
|
<name>
|
||||||
FTP PASV upload ASCII file already using CRLF
|
FTP PASV upload ASCII file already using CRLF
|
||||||
</name>
|
</name>
|
||||||
<file name="%LOGDIR/test%TESTNUMBER.txt" crlf="yes">
|
<file name="%LOGDIR/test%TESTNUMBER.txt" nonewline="yes">
|
||||||
%repeat[1750 x a line of text used for verifying this !%0a]%
|
%repeat[1750 x a line of text used for verifying this !%0d%0a]%
|
||||||
</file>
|
</file>
|
||||||
<command>
|
<command>
|
||||||
"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt
|
"ftp://%HOSTIP:%FTPPORT/%TESTNUMBER;type=a" -T %LOGDIR/test%TESTNUMBER.txt
|
||||||
@ -29,7 +29,7 @@ FTP PASV upload ASCII file already using CRLF
|
|||||||
<strip>
|
<strip>
|
||||||
QUIT
|
QUIT
|
||||||
</strip>
|
</strip>
|
||||||
<upload crlf="yes">
|
<upload crlf="yes" nonewline="yes">
|
||||||
%repeat[1750 x a line of text used for verifying this !%0a]%
|
%repeat[1750 x a line of text used for verifying this !%0a]%
|
||||||
</upload>
|
</upload>
|
||||||
<protocol>
|
<protocol>
|
||||||
|
|||||||
@ -1497,6 +1497,11 @@ sub singletest_check {
|
|||||||
if($hash{'crlf'}) {
|
if($hash{'crlf'}) {
|
||||||
subnewlines(1, \$_) for @upload;
|
subnewlines(1, \$_) for @upload;
|
||||||
}
|
}
|
||||||
|
if($hash{'nonewline'}) {
|
||||||
|
# Yes, we must cut off the final newline from the final line
|
||||||
|
# of the upload data
|
||||||
|
chomp($upload[-1]);
|
||||||
|
}
|
||||||
|
|
||||||
$res = compare($runnerid, $testnum, $testname, "upload", \@out, \@upload);
|
$res = compare($runnerid, $testnum, $testname, "upload", \@out, \@upload);
|
||||||
if ($res) {
|
if ($res) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user