diff options
author | Richard Hughes <richard@hughsie.com> | 2017-12-13 22:56:17 +0000 |
---|---|---|
committer | Richard Hughes <richard@hughsie.com> | 2017-12-14 10:25:46 +0000 |
commit | 47d4e91a16dc794f8389b1f1f53d491b7d9e12b9 (patch) | |
tree | c92ba6db270327dcf387618e0b7ddef5eb0d60a1 | |
parent | 806e1c4b92d1830028e6675a86ee345aecfd6851 (diff) | |
download | gcab-47d4e91a16dc794f8389b1f1f53d491b7d9e12b9.tar.gz |
Fix a large memory leak when parsing LZX cab files
-rw-r--r-- | libgcab/cabinet.c | 7 | ||||
-rw-r--r-- | libgcab/decomp.c | 5 | ||||
-rw-r--r-- | 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 |