Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

uniq(1) is broken



uniq(1) is currently broken:

  % cat test
  1
  12
  1
  1
  % uniq test
  1
  12
  1
  1

This bug was introduced to uniq.c rev. 1.19,

  http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/uniq/uniq.c#rev1.19

where the size of buffer and the length of line are mixed up.
Please apply the attached patch. Beside fixing this bug, a tiny
optimization has been made; do not call skip() twice per line.

Thanks,
Rin
====
--- src/usr.bin/uniq/uniq.c.orig	2016-10-16 08:11:18.115254706 +0900
+++ src/usr.bin/uniq/uniq.c	2016-10-16 09:33:36.693367693 +0900
@@ -65,12 +65,12 @@
 int
 main (int argc, char *argv[])
 {
-	const char *t1, *t2;
+	const char *prevp, *thisp;
 	FILE *ifp, *ofp;
 	int ch;
 	char *prevline, *thisline, *p;
 	size_t prevlinesize, thislinesize, psize;
-	size_t prevlinecompsize, thislinecompsize;
+	size_t prevlen, thislen;
setprogname(argv[0]);
 	ifp = ofp = NULL;
@@ -127,11 +127,15 @@
if ((p = fgetln(ifp, &psize)) == NULL)
 		return 0;
-	prevlinesize = psize;
+	prevlinesize = prevlen = psize;
 	if ((prevline = malloc(prevlinesize + 1)) == NULL)
 		err(1, "malloc");
 	(void)memcpy(prevline, p, prevlinesize);
 	prevline[prevlinesize] = '\0';
+	if (numfields || numchars)
+		prevp = skip(prevline, &prevlen);
+	else
+		prevp = prevline;
thislinesize = psize;
 	if ((thisline = malloc(thislinesize + 1)) == NULL)
@@ -143,22 +147,18 @@
 				err(1, "realloc");
 			thislinesize = psize;
 		}
+		thislen = psize;
 		(void)memcpy(thisline, p, psize);
 		thisline[psize] = '\0';
-		thislinecompsize = thislinesize;
-		prevlinecompsize = prevlinesize;
/* If requested get the chosen fields + character offsets. */
-		if (numfields || numchars) {
-			t1 = skip(thisline, &thislinecompsize);
-			t2 = skip(prevline, &prevlinecompsize);
-		} else {
-			t1 = thisline;
-			t2 = prevline;
-		}
+		if (numfields || numchars)
+			thisp = skip(thisline, &thislen);
+		else
+			thisp = thisline;
/* If different, print; set previous to new value. */
-		if (thislinecompsize != prevlinecompsize || strcmp(t1, t2)) {
+		if (thislen != prevlen || strcmp(thisp, prevp)) {
 			char *t;
 			size_t ts;
@@ -169,6 +169,8 @@
 			ts = prevlinesize;
 			prevlinesize = thislinesize;
 			thislinesize = ts;
+			prevp = thisp;
+			prevlen = thislen;
 			repeats = 0;
 		} else
 			++repeats;


Home | Main Index | Thread Index | Old Index