From nobody@FreeBSD.org  Sat Nov 28 16:59:55 2009
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 16E25106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 28 Nov 2009 16:59:55 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 05E9F8FC1D
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 28 Nov 2009 16:59:55 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id nASGxsmH077805
	for <freebsd-gnats-submit@FreeBSD.org>; Sat, 28 Nov 2009 16:59:54 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id nASGxsoS077804;
	Sat, 28 Nov 2009 16:59:54 GMT
	(envelope-from nobody)
Message-Id: <200911281659.nASGxsoS077804@www.freebsd.org>
Date: Sat, 28 Nov 2009 16:59:54 GMT
From: "D'Arcy Cain" <darcy@NetBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Subject: comm(1) mishandles lines with tabs
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         140976
>Category:       bin
>Synopsis:       comm(1) mishandles lines with tabs
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    jh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Sat Nov 28 17:00:03 UTC 2009
>Closed-Date:    Tue Aug 17 15:24:14 UTC 2010
>Last-Modified:  Tue Aug 17 15:24:14 UTC 2010
>Originator:     D'Arcy Cain
>Release:        7.2-RELEASE
>Organization:
NetBSD developer
>Environment:
FreeBSD shell.vex.net 7.2-RELEASE FreeBSD 7.2-RELEASE #0: Fri May  1 08:49:13 UTC 2009     root@walker.cse.buffalo.edu:/usr/obj/usr/src/sys/GENERIC  i386

>Description:
If an input file contains tabs it may not be handled correctly.  In fact, the problem would happen with any character that compares lower than newline.
>How-To-Repeat:
Run this script.  The two tests should print the same thing.

#! /bin/sh

TEST=/tmp/$$.test
trap "rm -f $TEST.*" 0

cat << MOUSE > $TEST.1a
a b
c d
e f
e f g
h i
MOUSE

cat << MOUSE > $TEST.1b
a b
e f g
MOUSE

tr ' ' '\t' < $TEST.1a > $TEST.2a
tr ' ' '\t' < $TEST.1b > $TEST.2b

echo "Test 1 (spaces) output:"
comm -12 $TEST.1a $TEST.1b

echo ""
echo "Test 2 (tabs) output:"
comm -12 $TEST.2a $TEST.2b

>Fix:
http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/comm/comm.c.diff?r1=1.17&r2=1.18&only_with_tag=MAIN&f=h is how I fixed it on NetBSD but you have a much different version of comm.c.  The basic fix is to not read the newline.  The newline is the separator between lines, not part of the line and including it causes it to be erroneously included in the comparisons.  sort(1) gets this right and that's where the problem occurs.  comm(1) does not agree with the sorting criteria.

In NetBSD current there is a library function called getline which more or less does what the getline included in comm.c does except that it doesn't return the newline.  Perhaps you should pull that in and use it instead.  Don't forget to change your printf statements to add the newline.

>Release-Note:
>Audit-Trail:

From: "D'Arcy J.M. Cain" <darcy@NetBSD.org>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/140976: comm(1) mishandles lines with tabs
Date: Sun, 29 Nov 2009 02:09:32 -0500

 My mistake - the NetBSD getline function does not stip out newlines.
 
 -- 
 D'Arcy J.M. Cain <darcy@NetBSD.org>
 http://www.NetBSD.org/

From: Jaakko Heinonen <jh@FreeBSD.org>
To: D'Arcy Cain <darcy@NetBSD.org>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/140976: comm(1) mishandles lines with tabs
Date: Tue, 1 Dec 2009 19:59:09 +0200

 On 2009-11-28, D'Arcy Cain wrote:
 > If an input file contains tabs it may not be handled correctly.  In
 > fact, the problem would happen with any character that compares lower
 > than newline.
 > 
 > The basic fix is to not read the newline.  The newline is the
 > separator between lines, not part of the line and including it causes
 > it to be erroneously included in the comparisons.
 
 Maybe something like this?
 
 http://people.freebsd.org/~jh/patches/comm-newline.diff
 
 -- 
 Jaakko
Responsible-Changed-From-To: freebsd-bugs->jh 
Responsible-Changed-By: jh 
Responsible-Changed-When: Sat Dec 12 16:18:04 UTC 2009 
Responsible-Changed-Why:  
Take. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140976 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/140976: commit references a PR
Date: Sat, 12 Dec 2009 18:19:00 +0000 (UTC)

 Author: jh
 Date: Sat Dec 12 18:18:46 2009
 New Revision: 200442
 URL: http://svn.freebsd.org/changeset/base/200442
 
 Log:
   Don't read the newline character to line buffer because lines are passed
   to wcscoll(3). Newline characters could cause incorrect results when
   comparing lines.
   
   Also, if an input line didn't contain a newline character, it was
   omitted from the output. According to my interpretation, SUSv3 requires
   that the newline is always printed.
   
   Add regression tests for the cases. [1]
   
   PR:		bin/140976
   Submitted by:	D'Arcy Cain (original version) [1]
   Approved by:	trasz (mentor)
 
 Added:
   head/tools/regression/usr.bin/comm/
   head/tools/regression/usr.bin/comm/Makefile   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.00.out   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.00a.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.00b.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.01.out   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.01a.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.01b.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.02.out   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.02a.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.02b.in   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.sh   (contents, props changed)
   head/tools/regression/usr.bin/comm/regress.t   (contents, props changed)
 Modified:
   head/tools/regression/usr.bin/Makefile
   head/usr.bin/comm/comm.c
 
 Modified: head/tools/regression/usr.bin/Makefile
 ==============================================================================
 --- head/tools/regression/usr.bin/Makefile	Sat Dec 12 18:04:50 2009	(r200441)
 +++ head/tools/regression/usr.bin/Makefile	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	calendar file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm
 +SUBDIR=	calendar comm file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm
  
  .include <bsd.subdir.mk>
 
 Added: head/tools/regression/usr.bin/comm/Makefile
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/Makefile	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,4 @@
 +# $FreeBSD$
 +
 +all:
 +	@m4 ${.CURDIR}/../regress.m4 ${.CURDIR}/regress.sh | sh /dev/stdin ${.CURDIR}
 
 Added: head/tools/regression/usr.bin/comm/regress.00.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.00.out	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,2 @@
 +a b
 +e f g
 
 Added: head/tools/regression/usr.bin/comm/regress.00a.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.00a.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,5 @@
 +a b
 +c d
 +e f
 +e f g
 +h i
 
 Added: head/tools/regression/usr.bin/comm/regress.00b.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.00b.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,2 @@
 +a b
 +e f g
 
 Added: head/tools/regression/usr.bin/comm/regress.01.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.01.out	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,2 @@
 +a	b
 +e	f	g
 
 Added: head/tools/regression/usr.bin/comm/regress.01a.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.01a.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,5 @@
 +a	b
 +c	d
 +e	f
 +e	f	g
 +h	i
 
 Added: head/tools/regression/usr.bin/comm/regress.01b.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.01b.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,2 @@
 +a	b
 +e	f	g
 
 Added: head/tools/regression/usr.bin/comm/regress.02.out
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.02.out	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,5 @@
 +a
 +b
 +		c
 +	d
 +	e
 
 Added: head/tools/regression/usr.bin/comm/regress.02a.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.02a.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,3 @@
 +a
 +b
 +c
 \ No newline at end of file
 
 Added: head/tools/regression/usr.bin/comm/regress.02b.in
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.02b.in	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,3 @@
 +c
 +d
 +e
 \ No newline at end of file
 
 Added: head/tools/regression/usr.bin/comm/regress.sh
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.sh	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,13 @@
 +# $FreeBSD$
 +
 +LC_ALL=C; export LC_ALL
 +
 +echo 1..3
 +
 +REGRESSION_START($1)
 +
 +REGRESSION_TEST(`00', `comm -12 regress.00a.in regress.00b.in')
 +REGRESSION_TEST(`01', `comm -12 regress.01a.in regress.01b.in')
 +REGRESSION_TEST(`02', `comm regress.02a.in regress.02b.in')
 +
 +REGRESSION_END()
 
 Added: head/tools/regression/usr.bin/comm/regress.t
 ==============================================================================
 --- /dev/null	00:00:00 1970	(empty, because file is newly added)
 +++ head/tools/regression/usr.bin/comm/regress.t	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -0,0 +1,6 @@
 +#!/bin/sh
 +# $FreeBSD$
 +
 +cd `dirname $0`
 +
 +m4 ../regress.m4 regress.sh | sh
 
 Modified: head/usr.bin/comm/comm.c
 ==============================================================================
 --- head/usr.bin/comm/comm.c	Sat Dec 12 18:04:50 2009	(r200441)
 +++ head/usr.bin/comm/comm.c	Sat Dec 12 18:18:46 2009	(r200442)
 @@ -163,7 +163,7 @@ main(int argc, char *argv[])
  		if (!comp) {
  			read1 = read2 = 1;
  			if (col3 != NULL)
 -				(void)printf("%ls%ls", col3, line1);
 +				(void)printf("%ls%ls\n", col3, line1);
  			continue;
  		}
  
 @@ -172,12 +172,12 @@ main(int argc, char *argv[])
  			read1 = 1;
  			read2 = 0;
  			if (col1 != NULL)
 -				(void)printf("%ls%ls", col1, line1);
 +				(void)printf("%ls%ls\n", col1, line1);
  		} else {
  			read1 = 0;
  			read2 = 1;
  			if (col2 != NULL)
 -				(void)printf("%ls%ls", col2, line2);
 +				(void)printf("%ls%ls\n", col2, line2);
  		}
  	}
  	exit(0);
 @@ -190,19 +190,16 @@ getline(wchar_t *buf, size_t *buflen, FI
  	wint_t ch;
  
  	bufpos = 0;
 -	do {
 -		if ((ch = getwc(fp)) != WEOF) {
 -			if (bufpos + 2 >= *buflen) {
 -				*buflen = *buflen * 2;
 -				buf = reallocf(buf, *buflen * sizeof(*buf));
 -				if (buf == NULL)
 -					return (NULL);
 -			}
 -			buf[bufpos++] = ch;
 +	while ((ch = getwc(fp)) != WEOF && ch != '\n') {
 +		if (bufpos + 1 >= *buflen) {
 +			*buflen = *buflen * 2;
 +			buf = reallocf(buf, *buflen * sizeof(*buf));
 +			if (buf == NULL)
 +				return (NULL);
  		}
 -	} while (ch != WEOF && ch != '\n');
 -	if (bufpos + 1 != *buflen)
 -		buf[bufpos] = '\0';
 +		buf[bufpos++] = ch;
 +	}
 +	buf[bufpos] = '\0';
  
  	return (bufpos != 0 || ch == '\n' ? buf : NULL);
  }
 @@ -212,7 +209,7 @@ show(FILE *fp, const char *fn, const wch
  {
  
  	do {
 -		(void)printf("%ls%ls", offset, buf);
 +		(void)printf("%ls%ls\n", offset, buf);
  	} while ((buf = getline(buf, buflen, fp)) != NULL);
  	if (ferror(fp))
  		err(1, "%s", fn);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->patched 
State-Changed-By: jh 
State-Changed-When: Sat Dec 12 18:51:35 UTC 2009 
State-Changed-Why:  
Patched in head (r200442). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140976 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/140976: commit references a PR
Date: Tue, 17 Aug 2010 15:02:43 +0000 (UTC)

 Author: jh
 Date: Tue Aug 17 15:02:33 2010
 New Revision: 211428
 URL: http://svn.freebsd.org/changeset/base/211428
 
 Log:
   MFC r200442:
   
   Don't read the newline character to line buffer because lines are passed
   to wcscoll(3). Newline characters could cause incorrect results when
   comparing lines.
   
   Also, if an input line didn't contain a newline character, it was
   omitted from the output. According to my interpretation, SUSv3 requires
   that the newline is always printed.
   
   Add regression tests for the cases.
   
   PR:		bin/140976
   
   MFC r200604:
   
   - Prevent overflowing of the buffer length variable in getline() by
     limiting its maximum value.
   - Exit if reallocf(3) fails in getline(). Failure was silently
     considered as end-of-file.
   
   MFC r204896 by ache:
   
   Rewrite input processing to not exit with error on the first EILSEQ found
   in the input data but fallback to "binary comparison" instead.
   
   POSIX says: "The input files shall be text files", nothing more,
   so the text file with illegal sequence is valid input.
   BTW, GNU sort does not fails on EILSEQ too.
   
   MFC r204928 by ache:
   
   Add SIZE_MAX overflow check
 
 Added:
   stable/8/tools/regression/usr.bin/comm/
      - copied from r200442, head/tools/regression/usr.bin/comm/
 Modified:
   stable/8/tools/regression/usr.bin/Makefile
   stable/8/usr.bin/comm/comm.c
 Directory Properties:
   stable/8/tools/regression/usr.bin/   (props changed)
   stable/8/tools/regression/usr.bin/pkill/pgrep-_g.t   (props changed)
   stable/8/tools/regression/usr.bin/pkill/pgrep-_s.t   (props changed)
   stable/8/tools/regression/usr.bin/pkill/pkill-_g.t   (props changed)
   stable/8/tools/regression/usr.bin/sed/   (props changed)
   stable/8/usr.bin/comm/   (props changed)
 
 Modified: stable/8/tools/regression/usr.bin/Makefile
 ==============================================================================
 --- stable/8/tools/regression/usr.bin/Makefile	Tue Aug 17 13:02:08 2010	(r211427)
 +++ stable/8/tools/regression/usr.bin/Makefile	Tue Aug 17 15:02:33 2010	(r211428)
 @@ -1,5 +1,5 @@
  # $FreeBSD$
  
 -SUBDIR=	apply calendar file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm
 +SUBDIR=	apply calendar comm file2c join jot m4 printf sed tr uudecode uuencode xargs lastcomm
  
  .include <bsd.subdir.mk>
 
 Modified: stable/8/usr.bin/comm/comm.c
 ==============================================================================
 --- stable/8/usr.bin/comm/comm.c	Tue Aug 17 13:02:08 2010	(r211427)
 +++ stable/8/usr.bin/comm/comm.c	Tue Aug 17 15:02:33 2010	(r211428)
 @@ -52,6 +52,8 @@ __FBSDID("$FreeBSD$");
  #include <err.h>
  #include <limits.h>
  #include <locale.h>
 +#include <stdint.h>
 +#define _WITH_GETLINE
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
 @@ -59,39 +61,31 @@ __FBSDID("$FreeBSD$");
  #include <wchar.h>
  #include <wctype.h>
  
 -#define	MAXLINELEN	(LINE_MAX + 1)
 -
 -const wchar_t *tabs[] = { L"", L"\t", L"\t\t" };
 +int iflag;
 +const char *tabs[] = { "", "\t", "\t\t" };
  
  FILE   *file(const char *);
 -wchar_t	*getline(wchar_t *, size_t *, FILE *);
 -void	show(FILE *, const char *, const wchar_t *, wchar_t *, size_t *);
 -int     wcsicoll(const wchar_t *, const wchar_t *);
 +wchar_t	*convert(const char *);
 +void	show(FILE *, const char *, const char *, char **, size_t *);
  static void	usage(void);
  
  int
  main(int argc, char *argv[])
  {
  	int comp, read1, read2;
 -	int ch, flag1, flag2, flag3, iflag;
 +	int ch, flag1, flag2, flag3;
  	FILE *fp1, *fp2;
 -	const wchar_t *col1, *col2, *col3;
 +	const char *col1, *col2, *col3;
  	size_t line1len, line2len;
 -	wchar_t *line1, *line2;
 -	const wchar_t **p;
 -
 -	flag1 = flag2 = flag3 = 1;
 -	iflag = 0;
 -
 - 	line1len = MAXLINELEN;
 - 	line2len = MAXLINELEN;
 - 	line1 = malloc(line1len * sizeof(*line1));
 - 	line2 = malloc(line2len * sizeof(*line2));
 -	if (line1 == NULL || line2 == NULL)
 -		err(1, "malloc");
 +	char *line1, *line2;
 +	ssize_t n1, n2;
 +	wchar_t *tline1, *tline2;
 +	const char **p;
  
  	(void) setlocale(LC_ALL, "");
  
 +	flag1 = flag2 = flag3 = 1;
 +
  	while ((ch = getopt(argc, argv, "123i")) != -1)
  		switch(ch) {
  		case '1':
 @@ -129,41 +123,57 @@ main(int argc, char *argv[])
  	if (flag3)
  		col3 = *p;
  
 +	line1len = line2len = 0;
 +	line1 = line2 = NULL;
 +	n1 = n2 = -1;
 +
  	for (read1 = read2 = 1;;) {
  		/* read next line, check for EOF */
  		if (read1) {
 -			line1 = getline(line1, &line1len, fp1);
 -			if (line1 == NULL && ferror(fp1))
 +			n1 = getline(&line1, &line1len, fp1);
 +			if (n1 < 0 && ferror(fp1))
  				err(1, "%s", argv[0]);
 +			if (n1 > 0 && line1[n1 - 1] == '\n')
 +				line1[n1 - 1] = '\0';
 +
  		}
  		if (read2) {
 -			line2 = getline(line2, &line2len, fp2);
 -			if (line2 == NULL && ferror(fp2))
 +			n2 = getline(&line2, &line2len, fp2);
 +			if (n2 < 0 && ferror(fp2))
  				err(1, "%s", argv[1]);
 +			if (n2 > 0 && line2[n2 - 1] == '\n')
 +				line2[n2 - 1] = '\0';
  		}
  
  		/* if one file done, display the rest of the other file */
 -		if (line1 == NULL) {
 -			if (line2 != NULL && col2 != NULL)
 -				show(fp2, argv[1], col2, line2, &line2len);
 +		if (n1 < 0) {
 +			if (n2 >= 0 && col2 != NULL)
 +				show(fp2, argv[1], col2, &line2, &line2len);
  			break;
  		}
 -		if (line2 == NULL) {
 -			if (line1 != NULL && col1 != NULL)
 -				show(fp1, argv[0], col1, line1, &line1len);
 +		if (n2 < 0) {
 +			if (n1 >= 0 && col1 != NULL)
 +				show(fp1, argv[0], col1, &line1, &line1len);
  			break;
  		}
  
 -		/* lines are the same */
 -		if(iflag)
 -			comp = wcsicoll(line1, line2);
 +		tline2 = NULL;
 +		if ((tline1 = convert(line1)) != NULL)
 +			tline2 = convert(line2);
 +		if (tline1 == NULL || tline2 == NULL)
 +			comp = strcmp(line1, line2);
  		else
 -			comp = wcscoll(line1, line2);
 +			comp = wcscoll(tline1, tline2);
 +		if (tline1 != NULL)
 +			free(tline1);
 +		if (tline2 != NULL)
 +			free(tline2);
  
 +		/* lines are the same */
  		if (!comp) {
  			read1 = read2 = 1;
  			if (col3 != NULL)
 -				(void)printf("%ls%ls", col3, line1);
 +				(void)printf("%s%s\n", col3, line1);
  			continue;
  		}
  
 @@ -172,48 +182,52 @@ main(int argc, char *argv[])
  			read1 = 1;
  			read2 = 0;
  			if (col1 != NULL)
 -				(void)printf("%ls%ls", col1, line1);
 +				(void)printf("%s%s\n", col1, line1);
  		} else {
  			read1 = 0;
  			read2 = 1;
  			if (col2 != NULL)
 -				(void)printf("%ls%ls", col2, line2);
 +				(void)printf("%s%s\n", col2, line2);
  		}
  	}
  	exit(0);
  }
  
  wchar_t *
 -getline(wchar_t *buf, size_t *buflen, FILE *fp)
 +convert(const char *str)
  {
 -	size_t bufpos;
 -	wint_t ch;
 +	size_t n;
 +	wchar_t *buf, *p;
  
 -	bufpos = 0;
 -	do {
 -		if ((ch = getwc(fp)) != WEOF) {
 -			if (bufpos + 2 >= *buflen) {
 -				*buflen = *buflen * 2;
 -				buf = reallocf(buf, *buflen * sizeof(*buf));
 -				if (buf == NULL)
 -					return (NULL);
 -			}
 -			buf[bufpos++] = ch;
 -		}
 -	} while (ch != WEOF && ch != '\n');
 -	if (bufpos + 1 != *buflen)
 -		buf[bufpos] = '\0';
 +	if ((n = mbstowcs(NULL, str, 0)) == (size_t)-1)
 +		return (NULL);
 +	if (SIZE_MAX / sizeof(*buf) < n + 1)
 +		errx(1, "conversion buffer length overflow");
 +	if ((buf = malloc((n + 1) * sizeof(*buf))) == NULL)
 +		err(1, "malloc");
 +	if (mbstowcs(buf, str, n + 1) != n)
 +		errx(1, "internal mbstowcs() error");
 +
 +	if (iflag) {
 +		for (p = buf; *p != L'\0'; p++)
 +			*p = towlower(*p);
 +	}
  
 -	return (bufpos != 0 || ch == '\n' ? buf : NULL);
 +	return (buf);
  }
  
  void
 -show(FILE *fp, const char *fn, const wchar_t *offset, wchar_t *buf, size_t *buflen)
 +show(FILE *fp, const char *fn, const char *offset, char **bufp, size_t *buflenp)
  {
 +	ssize_t n;
  
  	do {
 -		(void)printf("%ls%ls", offset, buf);
 -	} while ((buf = getline(buf, buflen, fp)) != NULL);
 +		(void)printf("%s%s\n", offset, *bufp);
 +		if ((n = getline(bufp, buflenp, fp)) < 0)
 +			break;
 +		if (n > 0 && (*bufp)[n - 1] == '\n')
 +			(*bufp)[n - 1] = '\0';
 +	} while (1);
  	if (ferror(fp))
  		err(1, "%s", fn);
  }
 @@ -237,52 +251,3 @@ usage(void)
  	(void)fprintf(stderr, "usage: comm [-123i] file1 file2\n");
  	exit(1);
  }
 -
 -static size_t wcsicoll_l1_buflen = 0, wcsicoll_l2_buflen = 0;
 -static wchar_t *wcsicoll_l1_buf = NULL, *wcsicoll_l2_buf = NULL;
 -
 -int
 -wcsicoll(const wchar_t *s1, const wchar_t *s2)
 -{
 -	wchar_t *p;
 -	size_t l1, l2;
 -	size_t new_l1_buflen, new_l2_buflen;
 -
 -	l1 = wcslen(s1) + 1;
 -	l2 = wcslen(s2) + 1;
 -	new_l1_buflen = wcsicoll_l1_buflen;
 -	new_l2_buflen = wcsicoll_l2_buflen;
 -	while (new_l1_buflen < l1) {
 -		if (new_l1_buflen == 0)
 -			new_l1_buflen = MAXLINELEN;
 -		else
 -			new_l1_buflen *= 2;
 -	}
 -	while (new_l2_buflen < l2) {
 -		if (new_l2_buflen == 0)
 -			new_l2_buflen = MAXLINELEN;
 -		else
 -			new_l2_buflen *= 2;
 -	}
 -	if (new_l1_buflen > wcsicoll_l1_buflen) {
 -		wcsicoll_l1_buf = reallocf(wcsicoll_l1_buf, new_l1_buflen * sizeof(*wcsicoll_l1_buf));
 -		if (wcsicoll_l1_buf == NULL)
 -                	err(1, "reallocf");
 -		wcsicoll_l1_buflen = new_l1_buflen;
 -	}
 -	if (new_l2_buflen > wcsicoll_l2_buflen) {
 -		wcsicoll_l2_buf = reallocf(wcsicoll_l2_buf, new_l2_buflen * sizeof(*wcsicoll_l2_buf));
 -		if (wcsicoll_l2_buf == NULL)
 -                	err(1, "reallocf");
 -		wcsicoll_l2_buflen = new_l2_buflen;
 -	}
 -
 -	for (p = wcsicoll_l1_buf; *s1; s1++)
 -		*p++ = towlower(*s1);
 -	*p = '\0';
 -	for (p = wcsicoll_l2_buf; *s2; s2++)
 -		*p++ = towlower(*s2);
 -	*p = '\0';
 -
 -	return (wcscoll(wcsicoll_l1_buf, wcsicoll_l2_buf));
 -}
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: patched->closed 
State-Changed-By: jh 
State-Changed-When: Tue Aug 17 15:24:13 UTC 2010 
State-Changed-Why:  
Fixed in head and stable/8. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=140976 
>Unformatted:
