out that libcurl didn't deal with large responses from server commands, when
the single response was consisting of multiple lines but of a total size of
16KB or more. Dan Fandrich improved the ftp test script and provided test
case 1006 to repeat the problem, and I fixed the code to make sure this new
test case runs fine.
This commit is contained in:
Daniel Stenberg
2007-08-24 14:00:42 +00:00
parent d994fcf2b1
commit 7cba40b218
5 changed files with 116 additions and 39 deletions

View File

@@ -6,6 +6,14 @@
Changelog Changelog
Daniel S (24 August 2007)
- Bug report #1779054 (http://curl.haxx.se/bug/view.cgi?id=1779054) pointed
out that libcurl didn't deal with large responses from server commands, when
the single response was consisting of multiple lines but of a total size of
16KB or more. Dan Fandrich improved the ftp test script and provided test
case 1006 to repeat the problem, and I fixed the code to make sure this new
test case runs fine.
Patrick M (23 August 2007) Patrick M (23 August 2007)
- OS/400 port: new files lib/config-os400.h lib/setup-os400.h packages/OS400/*. - OS/400 port: new files lib/config-os400.h lib/setup-os400.h packages/OS400/*.
See packages/OS400/README.OS400. See packages/OS400/README.OS400.

View File

@@ -45,7 +45,7 @@ This release includes the following bugfixes:
o resume HTTP PUT using Digest authentication o resume HTTP PUT using Digest authentication
o FTP NOBODY requests on directories sent "SIZE (null)" o FTP NOBODY requests on directories sent "SIZE (null)"
o FTP NOBODY request on file crash o FTP NOBODY request on file crash
o excessively long FTP server response lines o excessively long FTP server responses and response lines
o file:// upload then FTP:// upload crash o file:// upload then FTP:// upload crash
This release includes the following known bugs: This release includes the following known bugs:

View File

@@ -424,6 +424,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ftpc->linestart_resp = ptr+1; ftpc->linestart_resp = ptr+1;
} }
} }
if(!keepon && (i != gotbytes)) { if(!keepon && (i != gotbytes)) {
/* We found the end of the response lines, but we didn't parse the /* We found the end of the response lines, but we didn't parse the
full chunk of data we have read from the server. We therefore need full chunk of data we have read from the server. We therefore need
@@ -436,26 +437,45 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
else else
return CURLE_OUT_OF_MEMORY; /**BANG**/ return CURLE_OUT_OF_MEMORY; /**BANG**/
} }
else if(keepon && (i == gotbytes) && (gotbytes > BUFSIZE/2)) { else if(keepon) {
int clipamount = 0;
bool restart = FALSE;
if((perline == gotbytes) && (gotbytes > BUFSIZE/2)) {
/* We got an excessive line without newlines and we need to deal /* 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 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 code and then we keep just that in the line cache. Then throw
away the rest. */ away the rest. */
infof(data, "Excessive FTP response line length received, %zd bytes." infof(data, "Excessive FTP response line length received, %zd bytes."
" Stripping\n", gotbytes); " Stripping\n", gotbytes);
if(STATUSCODE(ftpc->linestart_resp)) { restart = TRUE;
ftpc->cache_size = 4; /* we copy 4 bytes since after the three-digit if(STATUSCODE(ftpc->linestart_resp))
number there is a dash or a space and it /* we copy 4 bytes since after the three-digit number there is a
is significant */ dash or a space and it is significant */
clipamount = 4;
}
else if(perline && (ftpc->nread_resp > BUFSIZE/2)) {
/* We got a large chunk of data and there's still trailing data to
take care of, so we put that part in the "cache" and restart */
clipamount = perline;
restart = TRUE;
}
if(restart) {
if(clipamount) {
ftpc->cache_size = clipamount;
ftpc->cache = (char *)malloc((int)ftpc->cache_size); ftpc->cache = (char *)malloc((int)ftpc->cache_size);
if(ftpc->cache) if(ftpc->cache)
memcpy(ftpc->cache, ftpc->linestart_resp, (int)ftpc->cache_size); memcpy(ftpc->cache, ftpc->linestart_resp, (int)ftpc->cache_size);
else else
return CURLE_OUT_OF_MEMORY; return CURLE_OUT_OF_MEMORY;
} }
/* now we forget what we read and get a new chunk in the next loop /* now reset a few variables to start over nicely from the start of
and append to the small piece we might have put in the cache */ the big buffer */
ftpc->nread_resp = 0; ftpc->nread_resp = 0; /* start over from scratch in the buffer */
ptr = ftpc->linestart_resp = buf;
perline = 0;
}
} }
} /* there was data */ } /* there was data */

View File

@@ -43,4 +43,4 @@ EXTRA_DIST = test1 test108 test117 test127 test20 test27 test34 test46 \
test296 test297 test298 test610 test611 test612 test406 test407 test408 \ test296 test297 test298 test610 test611 test612 test406 test407 test408 \
test409 test613 test614 test700 test701 test702 test704 test705 test703 \ test409 test613 test614 test700 test701 test702 test704 test705 test703 \
test706 test707 test350 test351 test352 test353 test289 test540 test354 \ test706 test707 test350 test351 test352 test353 test289 test540 test354 \
test231 test1000 test1001 test1002 test1003 test1004 test1005 test231 test1000 test1001 test1002 test1003 test1004 test1005 test1006

49
tests/data/test1006 Normal file

File diff suppressed because one or more lines are too long