From owner-freebsd-bugs@FreeBSD.ORG Sat Feb 5 05:05:17 2005 Return-Path: Delivered-To: freebsd-bugs@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 30EC816A4CE for ; Sat, 5 Feb 2005 05:05:17 +0000 (GMT) Received: from mail.gmx.net (mail.gmx.de [213.165.64.20]) by mx1.FreeBSD.org (Postfix) with SMTP id 3C6D143D41 for ; Sat, 5 Feb 2005 05:05:16 +0000 (GMT) (envelope-from m@MHoerich.de) Received: (qmail invoked by alias); 05 Feb 2005 05:05:10 -0000 Received: from pD9E58B80.dip.t-dialin.net (EHLO localhost) (217.229.139.128) by mail.gmx.net (mp007) with SMTP; 05 Feb 2005 06:05:10 +0100 X-Authenticated: #5114400 Date: Sat, 5 Feb 2005 06:04:49 +0100 From: Mario Hoerich To: freebsd-bugs@freebsd.org Message-ID: <20050205050449.GA31765@Pandora.MHoerich.de> References: <200502040930.j149UQDc043307@freefall.freebsd.org> <20050204201622.GA29998@Pandora.MHoerich.de> <20050204231405.GD9766@eyore.cobbled.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20050204231405.GD9766@eyore.cobbled.net> User-Agent: Mutt/1.4.2.1i Organization: University of Paderborn X-Y-GMX-Trusted: 0 cc: Fergus Cameron Subject: Re: bin/77031: [patch] comm(1) unable to handle lines greater than LINE_MAX (2048) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Feb 2005 05:05:17 -0000 # Fergus Cameron: [ My patch ] > personally i think you should post it 'as is' even if you > don't think it's worth putting extra effort into. the neater > reference is good to have in the PR. (See below) [ Loop termination ] > > that is the only case it terminates at. i think my comments > must be ill concieved because the comment directly above > states > > "... stop at EOF (nb: will break from loop at end of line)" Ooops. It wasn't your comments at fault here, it was a rather bad case of problem between keyboard and chair. Should have read the code in a quieter moment. My apologies for that. Anyway, I managed to dig up both coffee and time and changed my code to get rid of at least some malloc()ing. Don't see an easy way to merge with your patchset though. Regards, Mario Index: comm.c =================================================================== RCS file: /home/ncvs/src/usr.bin/comm/comm.c,v retrieving revision 1.21 diff -u -r1.21 comm.c --- comm.c 2 Jul 2004 22:48:29 -0000 1.21 +++ comm.c 5 Feb 2005 04:45:31 -0000 @@ -59,14 +59,19 @@ #include #include -#define MAXLINELEN (LINE_MAX + 1) +struct wcstr { + wchar_t *data; + size_t len; +}; +typedef struct wcstr wcstr_t; const wchar_t *tabs[] = { L"", L"\t", L"\t\t" }; FILE *file(const char *); -void show(FILE *, const char *, const wchar_t *, wchar_t *); +void show(FILE *, const char *, const wchar_t *, wcstr_t *); int wcsicoll(const wchar_t *, const wchar_t *); -static void usage(void); +wchar_t *fgetwlna(FILE *, wcstr_t *); +static void usage(void); int main(int argc, char *argv[]) @@ -75,8 +80,8 @@ int ch, flag1, flag2, flag3, iflag; FILE *fp1, *fp2; const wchar_t *col1, *col2, *col3; - wchar_t line1[MAXLINELEN], line2[MAXLINELEN]; const wchar_t **p; + wcstr_t line1, line2; flag1 = flag2 = flag3 = 1; iflag = 0; @@ -119,16 +124,18 @@ col2 = *p++; if (flag3) col3 = *p; - + + memset(&line1, 0, sizeof(wcstr_t)); + memset(&line2, 0, sizeof(wcstr_t)); for (read1 = read2 = 1;;) { /* read next line, check for EOF */ if (read1) { - file1done = !fgetws(line1, MAXLINELEN, fp1); + file1done = !fgetwlna(fp1, &line1); if (file1done && ferror(fp1)) err(1, "%s", argv[0]); } if (read2) { - file2done = !fgetws(line2, MAXLINELEN, fp2); + file2done = !fgetwlna(fp2, &line2); if (file2done && ferror(fp2)) err(1, "%s", argv[1]); } @@ -136,25 +143,25 @@ /* if one file done, display the rest of the other file */ if (file1done) { if (!file2done && col2) - show(fp2, argv[1], col2, line2); + show(fp2, argv[1], col2, &line2); break; } if (file2done) { if (!file1done && col1) - show(fp1, argv[0], col1, line1); + show(fp1, argv[0], col1, &line1); break; } /* lines are the same */ if(iflag) - comp = wcsicoll(line1, line2); + comp = wcsicoll(line1.data, line2.data); else - comp = wcscoll(line1, line2); + comp = wcscoll(line1.data, line2.data); if (!comp) { read1 = read2 = 1; if (col3) - (void)printf("%ls%ls", col3, line1); + (void)printf("%ls%ls", col3, line1.data); continue; } @@ -163,24 +170,25 @@ read1 = 1; read2 = 0; if (col1) - (void)printf("%ls%ls", col1, line1); + (void)printf("%ls%ls", col1, line1.data); } else { read1 = 0; read2 = 1; if (col2) - (void)printf("%ls%ls", col2, line2); + (void)printf("%ls%ls", col2, line2.data); } } + free(line1.data); + free(line2.data); exit(0); } void -show(FILE *fp, const char *fn, const wchar_t *offset, wchar_t *buf) +show(FILE *fp, const char *fn, const wchar_t *offset, wcstr_t *buf) { - do { - (void)printf("%ls%ls", offset, buf); - } while (fgetws(buf, MAXLINELEN, fp)); + (void)printf("%ls%ls", offset, buf->data); + } while (fgetwlna(fp, buf)); if (ferror(fp)) err(1, "%s", fn); } @@ -208,13 +216,52 @@ int wcsicoll(const wchar_t *s1, const wchar_t *s2) { - wchar_t *p, line1[MAXLINELEN], line2[MAXLINELEN]; - + wchar_t *p, *line1, *line2; + int cmp; + + if( (line1=malloc((wcslen(s1) + 1) * sizeof(wchar_t))) == NULL) + err(1, "%s", __func__); + + if( (line2=malloc((wcslen(s2) + 1) * sizeof(wchar_t))) == NULL) + err(1, "%s", __func__); + for (p = line1; *s1; s1++) *p++ = towlower(*s1); - *p = '\0'; + *p = L'\0'; for (p = line2; *s2; s2++) *p++ = towlower(*s2); - *p = '\0'; - return (wcscoll(line1, line2)); + *p = L'\0'; + + cmp = wcscoll(line1, line2); + free(line1); + free(line2); + + return cmp; +} + +wchar_t * +fgetwlna(FILE *fp, wcstr_t *str) +{ + size_t len; + wchar_t *wtmp; + + if(str == NULL) + errx(1, "%s: Empty string received.", __func__); + + if( (wtmp=fgetwln(fp,&len)) == NULL) + return NULL; + + /* Realloc if not enough space for string */ + if(str->len < len + 1) { + str->len = (len + 1); + str->data = reallocf(str->data, str->len * sizeof(wchar_t)); + if(str->data == NULL) + err(1, "%s", __func__); + } + + /* can't use wcscpy as wtmp doesn't end with L'\0' */ + wcsncpy(str->data, wtmp, len); + str->data[len] = L'\0'; + + return str->data; } --