Bug report #1779054 (http://curl.haxx.se/bug/view.cgi?id=1779054) pointed
out that libcurl didn't deal with very long (>16K) FTP server response lines properly. Starting now, libcurl will chop them off (thus the client app will not get the full line) but survive and deal with them fine otherwise. Test case 1003 was added to verify this.
This commit is contained in:
parent
c347db2e0a
commit
381e372939
7
CHANGES
7
CHANGES
@ -6,6 +6,13 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Daniel S (22 August 2007)
|
||||
- Bug report #1779054 (http://curl.haxx.se/bug/view.cgi?id=1779054) pointed
|
||||
out that libcurl didn't deal with very long (>16K) FTP server response lines
|
||||
properly. Starting now, libcurl will chop them off (thus the client app will
|
||||
not get the full line) but survive and deal with them fine otherwise. Test
|
||||
case 1003 was added to verify this.
|
||||
|
||||
Daniel S (20 August 2007)
|
||||
- Based on a patch by Christian Vogt, the FTP code now sets the upcoming
|
||||
download transfer size much earlier to be possible to get read with
|
||||
|
@ -44,6 +44,7 @@ This release includes the following bugfixes:
|
||||
o resume HTTP PUT using Digest authentication
|
||||
o FTP NOBODY requests on directories sent "SIZE (null)"
|
||||
o FTP NOBODY request on file crash
|
||||
o excessively long FTP server response lines
|
||||
|
||||
This release includes the following known bugs:
|
||||
|
||||
|
33
lib/ftp.c
33
lib/ftp.c
@ -287,9 +287,13 @@ static void ftp_respinit(struct connectdata *conn)
|
||||
ftpc->linestart_resp = conn->data->state.buffer;
|
||||
}
|
||||
|
||||
/* macro to check for a three-digit ftp status code at the start of the
|
||||
given string */
|
||||
#define STATUSCODE(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \
|
||||
ISDIGIT(line[2]))
|
||||
|
||||
/* macro to check for the last line in an FTP server response */
|
||||
#define lastline(line) (ISDIGIT(line[0]) && ISDIGIT(line[1]) && \
|
||||
ISDIGIT(line[2]) && (' ' == line[3]))
|
||||
#define LASTLINE(line) (STATUSCODE(line) && (' ' == line[3]))
|
||||
|
||||
static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
struct connectdata *conn,
|
||||
@ -399,7 +403,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(perline>3 && lastline(ftpc->linestart_resp)) {
|
||||
if(perline>3 && LASTLINE(ftpc->linestart_resp)) {
|
||||
/* This is the end of the last line, copy the last line to the
|
||||
start of the buffer and zero terminate, for old times sake (and
|
||||
krb4)! */
|
||||
@ -432,6 +436,27 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY; /**BANG**/
|
||||
}
|
||||
else if(keepon && (i == gotbytes) && (gotbytes > BUFSIZE/2)) {
|
||||
/* We got an excessive line without newlines and we need to deal
|
||||
with it. First, check if it seems to start with a valid status
|
||||
code and then we keep just that in the line cache. Then throw
|
||||
away the rest. */
|
||||
infof(data, "Excessive FTP response line length received, %zd bytes."
|
||||
" Stripping\n", gotbytes);
|
||||
if(STATUSCODE(ftpc->linestart_resp)) {
|
||||
ftpc->cache_size = 4; /* we copy 4 bytes since after the three-digit
|
||||
number there is a dash or a space and it
|
||||
is significant */
|
||||
ftpc->cache = (char *)malloc((int)ftpc->cache_size);
|
||||
if(ftpc->cache)
|
||||
memcpy(ftpc->cache, ftpc->linestart_resp, (int)ftpc->cache_size);
|
||||
else
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
/* now we forget what we read and get a new chunk in the next loop
|
||||
and append to the small piece we might have put in the cache */
|
||||
ftpc->nread_resp = 0;
|
||||
}
|
||||
} /* there was data */
|
||||
|
||||
} /* while there's buffer left and loop is requested */
|
||||
@ -645,7 +670,7 @@ CURLcode Curl_GetFTPResponse(ssize_t *nreadp, /* return number of bytes read */
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
if(perline>3 && lastline(line_start)) {
|
||||
if(perline>3 && LASTLINE(line_start)) {
|
||||
/* This is the end of the last line, copy the last
|
||||
* line to the start of the buffer and zero terminate,
|
||||
* for old times sake (and krb4)! */
|
||||
|
@ -43,4 +43,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
|
||||
test296 test297 test298 test610 test611 test612 test406 test407 test408 \
|
||||
test409 test613 test614 test700 test701 test702 test704 test705 test703 \
|
||||
test706 test707 test350 test351 test352 test353 test289 test540 test354 \
|
||||
test231 test1000 test1001 test1002
|
||||
test231 test1000 test1001 test1002 test1003
|
||||
|
48
tests/data/test1003
Normal file
48
tests/data/test1003
Normal file
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user