aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2008-08-11 23:16:08 +0000
committerDan Fandrich <dan@coneharvesters.com>2008-08-11 23:16:08 +0000
commitf1fe04245ac04b72d1380b6a75a46dcb335fd7ab (patch)
treea2db8de675ddc3d287757f690d7d63abf61ef3a5 /lib
parent8bb208e8f8d33a6cc0f670af1dcedc79764b83a1 (diff)
Fixed a boundary condition error in ftp_readresp() whereby a non-terminal
line of a multiline FTP response whose last byte landed exactly at the end of the BUFSIZE-length buffer would be treated as the terminal response line. The following response code read in would then actually be the end of the previous response line, and all responses from then on would correspond to the wrong command. Test case 1062 verifies this. Stop closing a never-opened ftp socket.
Diffstat (limited to 'lib')
-rw-r--r--lib/ftp.c31
1 files changed, 18 insertions, 13 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 819772b92..d53134d5b 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -388,7 +388,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
ssize_t gotbytes;
char *ptr;
struct SessionHandle *data = conn->data;
- char *buf = data->state.buffer;
+ char * const buf = data->state.buffer;
CURLcode result = CURLE_OK;
struct ftp_conn *ftpc = &conn->proto.ftpc;
int code = 0;
@@ -414,6 +414,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
* int to begin with, even though its datatype may be larger
* than an int.
*/
+ DEBUGASSERT((ptr+ftpc->cache_size) <= (buf+BUFSIZE+1));
memcpy(ptr, ftpc->cache, (int)ftpc->cache_size);
gotbytes = (int)ftpc->cache_size;
free(ftpc->cache); /* free the cache */
@@ -427,6 +428,7 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
conn->data_prot = 0;
#endif
+ DEBUGASSERT((ptr+BUFSIZE-ftpc->nread_resp) <= (buf+BUFSIZE+1));
res = Curl_read(conn, sockfd, ptr, BUFSIZE-ftpc->nread_resp,
&gotbytes);
#if defined(HAVE_KRB4) || defined(HAVE_GSSAPI)
@@ -535,9 +537,10 @@ static CURLcode ftp_readresp(curl_socket_t sockfd,
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 */
+ else if(ftpc->nread_resp > BUFSIZE/2) {
+ /* We got a large chunk of data and there's potentially still trailing
+ data to take care of, so we put any such part in the "cache", clear
+ the buffer to make space and restart. */
clipamount = perline;
restart = TRUE;
}
@@ -3224,17 +3227,19 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
shutdown(conn->sock[SECONDARYSOCKET],2); /* SD_BOTH */
#endif
- if(conn->ssl[SECONDARYSOCKET].use) {
- /* The secondary socket is using SSL so we must close down that part first
- before we close the socket for real */
- Curl_ssl_close(conn, SECONDARYSOCKET);
+ if(conn->sock[SECONDARYSOCKET] != CURL_SOCKET_BAD) {
+ if(conn->ssl[SECONDARYSOCKET].use) {
+ /* The secondary socket is using SSL so we must close down that part first
+ before we close the socket for real */
+ Curl_ssl_close(conn, SECONDARYSOCKET);
- /* Note that we keep "use" set to TRUE since that (next) connection is
- still requested to use SSL */
- }
- sclose(conn->sock[SECONDARYSOCKET]);
+ /* Note that we keep "use" set to TRUE since that (next) connection is
+ still requested to use SSL */
+ }
+ sclose(conn->sock[SECONDARYSOCKET]);
- conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
+ }
if((ftp->transfer == FTPTRANSFER_BODY) && !status && !premature) {
/*