Author: delphij
Date: Wed Feb  4 00:45:28 2015
New Revision: 278176
URL: https://svnweb.freebsd.org/changeset/base/278176

Log:
  MFC r277463:
  
  Fix xz handling for files larger than 32K.
  
  Submitted by: Stefan Ehmann <shoesoft gmx net>
  PR:           bin/186861

Modified:
  stable/9/usr.bin/grep/file.c
Directory Properties:
  stable/9/usr.bin/grep/   (props changed)

Modified: stable/9/usr.bin/grep/file.c
==============================================================================
--- stable/9/usr.bin/grep/file.c        Wed Feb  4 00:45:02 2015        
(r278175)
+++ stable/9/usr.bin/grep/file.c        Wed Feb  4 00:45:28 2015        
(r278176)
@@ -65,6 +65,8 @@ __FBSDID("$FreeBSD$");
 static gzFile gzbufdesc;
 #ifndef WITHOUT_LZMA
 static lzma_stream lstrm = LZMA_STREAM_INIT;
+static lzma_action laction;
+static uint8_t lin_buf[MAXBUFSIZ];
 #endif
 #ifndef WITHOUT_BZIP2
 static BZFILE* bzbufdesc;
@@ -123,34 +125,34 @@ grep_refill(struct file *f)
 #endif
 #ifndef WITHOUT_LZMA
        } else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) {
-               lzma_action action = LZMA_RUN;
-               uint8_t in_buf[MAXBUFSIZ];
                lzma_ret ret;
+               lstrm.next_out = buffer;
 
-               ret = (filebehave == FILE_XZ) ?
-                   lzma_stream_decoder(&lstrm, UINT64_MAX,
-                   LZMA_CONCATENATED) :
-                   lzma_alone_decoder(&lstrm, UINT64_MAX);
+               do {
+                       if (lstrm.avail_in == 0) {
+                               lstrm.next_in = lin_buf;
+                               nr = read(f->fd, lin_buf, MAXBUFSIZ);
+
+                               if (nr < 0)
+                                       return (-1);
+                               else if (nr == 0)
+                                       laction = LZMA_FINISH;
 
-               if (ret != LZMA_OK)
-                       return (-1);
+                               lstrm.avail_in = nr;
+                       }
 
-               lstrm.next_out = buffer;
-               lstrm.avail_out = MAXBUFSIZ;
-               lstrm.next_in = in_buf;
-               nr = read(f->fd, in_buf, MAXBUFSIZ);
+                       ret = lzma_code(&lstrm, laction);
+
+                       if (ret != LZMA_OK && ret != LZMA_STREAM_END)
+                               return (-1);
+
+                       if (lstrm.avail_out == 0 || ret == LZMA_STREAM_END) {
+                               bufrem = MAXBUFSIZ - lstrm.avail_out;
+                               lstrm.next_out = buffer;
+                               lstrm.avail_out = MAXBUFSIZ;
+                       }
+               } while (bufrem == 0 && ret != LZMA_STREAM_END);
 
-               if (nr < 0)
-                       return (-1);
-               else if (nr == 0)
-                       action = LZMA_FINISH;
-
-               lstrm.avail_in = nr;
-               ret = lzma_code(&lstrm, action);
-
-               if (ret != LZMA_OK && ret != LZMA_STREAM_END)
-                       return (-1);
-               bufrem = MAXBUFSIZ - lstrm.avail_out;
                return (0);
 #endif /* WIHTOUT_LZMA */
        } else
@@ -291,6 +293,23 @@ grep_open(const char *path)
            (bzbufdesc = BZ2_bzdopen(f->fd, "r")) == NULL)
                goto error2;
 #endif
+#ifndef WITHOUT_LZMA
+       else if ((filebehave == FILE_XZ) || (filebehave == FILE_LZMA)) {
+               lzma_ret ret;
+
+               ret = (filebehave == FILE_XZ) ?
+                       lzma_stream_decoder(&lstrm, UINT64_MAX,
+                                       LZMA_CONCATENATED) :
+                       lzma_alone_decoder(&lstrm, UINT64_MAX);
+
+               if (ret != LZMA_OK)
+                       goto error2;
+
+               lstrm.avail_in = 0;
+               lstrm.avail_out = MAXBUFSIZ;
+               laction = LZMA_RUN;
+       }
+#endif
 
        /* Fill read buffer, also catches errors early */
        if (bufrem == 0 && grep_refill(f) != 0)
_______________________________________________
svn-src-stable-9@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-stable-9
To unsubscribe, send any mail to "svn-src-stable-9-unsubscr...@freebsd.org"

Reply via email to