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;

Reply via email to