aboutsummaryrefslogtreecommitdiff
path: root/lib/ftp.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ftp.c')
-rw-r--r--lib/ftp.c33
1 files changed, 29 insertions, 4 deletions
diff --git a/lib/ftp.c b/lib/ftp.c
index 3ea07c0a2..8ecdca62e 100644
--- a/lib/ftp.c
+++ b/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)! */