This isn't a grave issue, but I came across it while exploring integer
overflow and think it's worth sharing.
grep represents line numbers with an int, which predictably overflows
for inputs with >= 2^31 newlines. This is easy to demonstrate using the
-n option and a debugging printf.
The below diff fixes this, and tunes up a for loop while I'm in there.
ok?
Index: grep.h
===================================================================
RCS file: /cvs/src/usr.bin/grep/grep.h,v
retrieving revision 1.22
diff -u -p -r1.22 grep.h
--- grep.h 16 Mar 2015 13:26:52 -0000 1.22
+++ grep.h 7 Dec 2015 06:26:55 -0000
@@ -43,7 +43,7 @@
typedef struct {
size_t len;
- int line_no;
+ size_t line_no;
off_t off;
char *file;
char *dat;
Index: util.c
===================================================================
RCS file: /cvs/src/usr.bin/grep/util.c,v
retrieving revision 1.50
diff -u -p -r1.50 util.c
--- util.c 25 Jun 2015 02:04:08 -0000 1.50
+++ util.c 7 Dec 2015 06:26:55 -0000
@@ -124,7 +124,7 @@ procfile(char *fn)
if (Bflag > 0)
initqueue();
- for (c = 0; c == 0 || !(lflag || qflag); ) {
+ for (c = 0; c == 0 || !(lflag || qflag); c += t) {
ln.off += ln.len + 1;
if ((ln.dat = grep_fgetln(f, &ln.len)) == NULL)
break;
@@ -138,7 +138,6 @@ procfile(char *fn)
enqueue(&ln);
linesqueued++;
}
- c += t;
}
if (Bflag > 0)
clearqueue();
@@ -623,7 +622,7 @@ printline(str_t *line, int sep, regmatch
if (nflag) {
if (n)
putchar(sep);
- printf("%d", line->line_no);
+ printf("%llu", (unsigned long long)line->line_no);
++n;
}
if (bflag) {