Date: Sat, 5 Feb 2005 06:04:49 +0100 From: Mario Hoerich <lists@MHoerich.de> To: freebsd-bugs@freebsd.org Cc: Fergus Cameron <fergus@cobbled.net> Subject: Re: bin/77031: [patch] comm(1) unable to handle lines greater than LINE_MAX (2048) Message-ID: <20050205050449.GA31765@Pandora.MHoerich.de> In-Reply-To: <20050204231405.GD9766@eyore.cobbled.net> References: <200502040930.j149UQDc043307@freefall.freebsd.org> <20050204201622.GA29998@Pandora.MHoerich.de> <20050204231405.GD9766@eyore.cobbled.net>
next in thread | previous in thread | raw e-mail | index | archive | help
# 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 <wchar.h> #include <wctype.h> -#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; } --
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050205050449.GA31765>