[gcab] Fix a large memory leak when parsing LZX cab files



commit 47d4e91a16dc794f8389b1f1f53d491b7d9e12b9
Author: Richard Hughes <richard hughsie com>
Date:   Wed Dec 13 22:56:17 2017 +0000

    Fix a large memory leak when parsing LZX cab files

 libgcab/cabinet.c |    7 +++++++
 libgcab/decomp.c  |    5 +++++
 libgcab/decomp.h  |    2 ++
 3 files changed, 14 insertions(+), 0 deletions(-)
---
diff --git a/libgcab/cabinet.c b/libgcab/cabinet.c
index a722c58..f7b8af3 100644
--- a/libgcab/cabinet.c
+++ b/libgcab/cabinet.c
@@ -471,6 +471,11 @@ cdata_finish (cdata_t *cd, GError **error)
     z_stream *z = &cd->z;
     int zret;
 
+    if (cd->decomp.comptype == GCAB_COMPRESSION_LZX) {
+        LZXfdi_clear (&cd->decomp);
+        return;
+    }
+
     if (!z->opaque)
         return;
 
@@ -537,6 +542,7 @@ cdata_read (cdata_t *cd, guint8 res_data, gint comptype,
             cd->decomp.fdi = &cd->fdi;
             cd->decomp.inbuf = cd->in;
             cd->decomp.outbuf = cd->out;
+            cd->decomp.comptype = compression;
 
             ret = LZXfdi_init((comptype >> 8) & 0x1f, &cd->decomp);
             if (ret < 0)
@@ -552,6 +558,7 @@ cdata_read (cdata_t *cd, guint8 res_data, gint comptype,
         if (cd->in[0] != 'C' || cd->in[1] != 'K')
             goto end;
 
+        cd->decomp.comptype = compression;
         z_stream *z = &cd->z;
 
         z->avail_in = cd->ncbytes - 2;
diff --git a/libgcab/decomp.c b/libgcab/decomp.c
index ad59ad8..64d97f8 100644
--- a/libgcab/decomp.c
+++ b/libgcab/decomp.c
@@ -836,6 +836,11 @@ int LZXfdi_init(int window, fdi_decomp_state *decomp_state) {
   return DECR_OK;
 }
 
+void LZXfdi_clear(fdi_decomp_state *decomp_state) {
+  cab_UBYTE *window = LZX(window);
+  CAB(fdi)->free(window);
+}
+
 /*******************************************************
  * LZXfdi_decomp(internal)
  */
diff --git a/libgcab/decomp.h b/libgcab/decomp.h
index 78b1b76..041d60e 100644
--- a/libgcab/decomp.h
+++ b/libgcab/decomp.h
@@ -241,10 +241,12 @@ typedef struct fdi_cds_fwd {
         struct ZIPstate zip;
         struct LZXstate lzx;
     } methods;
+    int comptype;
 } fdi_decomp_state;
 
 int ZIPfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state);
 int LZXfdi_decomp(int inlen, int outlen, fdi_decomp_state *decomp_state);
 int LZXfdi_init(int window, fdi_decomp_state *decomp_state);
+void LZXfdi_clear(fdi_decomp_state *decomp_state);
 
 #endif


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