bin/77031: [patch] comm(1) unable to handle lines greater than
LINE_MAX (2048)
Mario Hoerich
lists at MHoerich.de
Fri Feb 4 21:05:17 PST 2005
# 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;
}
--
More information about the freebsd-bugs
mailing list