[libxml2] Fix a bug loading some compressed files



commit a1313a6f8c48cc27b02f65aca6b04e6cd59d939a
Author: Mike Alexander <mta umich edu>
Date:   Thu Nov 28 23:21:23 2013 +0800

    Fix a bug loading some compressed files
    
    For https://bugzilla.gnome.org/show_bug.cgi?id=712528
    Related to https://bugzilla.redhat.com/show_bug.cgi?id=877567
    
    There is a bug in xzlib.c which causes certain compressed XML files to fail to
    load correctly.  The code in xz_decomp which attempts to verify the checksum
    and length of the expanded data fails if the checksum or length at the end of
    the file crosses a 1024 byte boundary.  It calls gz_next4 to get those two
    values.  This function uses the stream state in state->zstrm, but calls
    xz_avail which uses the state->strm stream info.  This causes gz_next4 to
    signal a premature EOF if the data it is fetching crosses a 1024 byte boundary.

 xzlib.c |   26 ++++++++++++++++++++++----
 1 files changed, 22 insertions(+), 4 deletions(-)
---
diff --git a/xzlib.c b/xzlib.c
index 150e803..0dcb9f4 100644
--- a/xzlib.c
+++ b/xzlib.c
@@ -270,6 +270,20 @@ xz_avail(xz_statep state)
     return 0;
 }
 
+#ifdef HAVE_ZLIB_H
+static int
+xz_avail_zstrm(xz_statep state)
+{
+    int ret;
+    state->strm.avail_in = state->zstrm.avail_in;
+    state->strm.next_in = state->zstrm.next_in;
+    ret = xz_avail(state);
+    state->zstrm.avail_in = (uInt) state->strm.avail_in;
+    state->zstrm.next_in = (Bytef *) state->strm.next_in;
+    return ret;
+}
+#endif
+
 static int
 is_format_xz(xz_statep state)
 {
@@ -339,6 +353,10 @@ is_format_lzma(xz_statep state)
 #define NEXT() ((strm->avail_in == 0 && xz_avail(state) == -1) ? -1 : \
                 (strm->avail_in == 0 ? -1 : \
                  (strm->avail_in--, *(strm->next_in)++)))
+/* Same thing, but from zstrm */
+#define NEXTZ() ((strm->avail_in == 0 && xz_avail_zstrm(state) == -1) ? -1 : \
+                (strm->avail_in == 0 ? -1 : \
+                 (strm->avail_in--, *(strm->next_in)++)))
 
 /* Get a four-byte little-endian integer and return 0 on success and the value
    in *ret.  Otherwise -1 is returned and *ret is not modified. */
@@ -349,10 +367,10 @@ gz_next4(xz_statep state, unsigned long *ret)
     unsigned long val;
     z_streamp strm = &(state->zstrm);
 
-    val = NEXT();
-    val += (unsigned) NEXT() << 8;
-    val += (unsigned long) NEXT() << 16;
-    ch = NEXT();
+    val = NEXTZ();
+    val += (unsigned) NEXTZ() << 8;
+    val += (unsigned long) NEXTZ() << 16;
+    ch = NEXTZ();
     if (ch == -1)
         return -1;
     val += (unsigned long) ch << 24;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]