bin/59285: [PATCH] /usr/libexec/ftpd has broken ASCII transfer type implementation

Andrey Beresovsky and at rsu.ru
Fri Nov 14 04:10:19 PST 2003


>Number:         59285
>Category:       bin
>Synopsis:       [PATCH] /usr/libexec/ftpd has broken ASCII transfer type implementation
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Nov 14 04:10:16 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Andrey Beresovsky
>Release:        FreeBSD 5.1-CURRENT i386
>Organization:
Rostov State University
>Environment:
System: FreeBSD 5.1-CURRENT #2: Fri Nov 7 22:15:49 MSK 2003 i386

>Description:
According to RFC 959 (FILE TRANSFER PROTOCOL) for ASCII transfer type "the <CRLF> sequence
should be used where necessary to denote the end of a line of text" (Chapter 3.1.1.1.).

ftpd server implements ASCII transfer type by inserting <CR> before each <LF> without 
checking that may be <CR> allready exists. It leads to <CR><CR><LF> sequences in 
files which allready had <CR><LF> end of lines (ex.: text files from Windows systems).

Attached patch should fix this problem.

This problem also exists in lukemftp and lukemftpd. I sent PR with patches to NetBSD.
See http://www.NetBSD.org/cgi-bin/query-pr-single.pl?number=23435.

>How-To-Repeat:
1. Create a text file with <CR><LF> end of lines.
2. Receive (GET) this file from FreeBSD ftpd server.
3. You'll get a file with <CR><CR><LF> EOLs on windows and <CRLF> on unixes.

>Fix:
(ftpd.c rev. 1.146)

--- ftpd.c.orig	Thu Nov 13 23:29:54 2003
+++ ftpd.c	Thu Nov 13 23:33:14 2003
@@ -1971,6 +1971,7 @@
 send_data(FILE *instr, FILE *outstr, off_t blksize, off_t filesize, int isreg)
 {
 	int c, filefd, netfd;
+	int d = '\0';
 	char *buf;
 	off_t cnt;
 
@@ -1982,12 +1983,13 @@
 			if (recvurg)
 				goto got_oob;
 			byte_count++;
-			if (c == '\n') {
+			if (c == '\n' && d != '\r') {
 				if (ferror(outstr))
 					goto data_err;
 				(void) putc('\r', outstr);
 			}
 			(void) putc(c, outstr);
+			d = c;
 		}
 		if (recvurg)
 			goto got_oob;
>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list