mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2025-10-28 23:14:57 +03:00
Fix a memory leak in the xzlib code
The freeing function wasn't called due to a bogus #ifdef surrounding value. Also switch the code to use the normal libxml2 allocation and freeing routines.
This commit is contained in:
64
xzlib.c
64
xzlib.c
@@ -37,6 +37,7 @@
|
|||||||
#include <lzma.h>
|
#include <lzma.h>
|
||||||
|
|
||||||
#include "xzlib.h"
|
#include "xzlib.h"
|
||||||
|
#include <libxml/xmlmemory.h>
|
||||||
|
|
||||||
/* values for xz_state how */
|
/* values for xz_state how */
|
||||||
#define LOOK 0 /* look for a gzip/lzma header */
|
#define LOOK 0 /* look for a gzip/lzma header */
|
||||||
@@ -68,6 +69,7 @@ typedef struct {
|
|||||||
int err; /* error code */
|
int err; /* error code */
|
||||||
char *msg; /* error message */
|
char *msg; /* error message */
|
||||||
/* lzma stream */
|
/* lzma stream */
|
||||||
|
int init; /* is the iniflate stream initialized */
|
||||||
lzma_stream strm; /* stream structure in-place (not a pointer) */
|
lzma_stream strm; /* stream structure in-place (not a pointer) */
|
||||||
char padding1[32]; /* padding allowing to cope with possible
|
char padding1[32]; /* padding allowing to cope with possible
|
||||||
extensions of above structure without
|
extensions of above structure without
|
||||||
@@ -87,7 +89,7 @@ xz_error(xz_statep state, int err, const char *msg)
|
|||||||
/* free previously allocated message and clear */
|
/* free previously allocated message and clear */
|
||||||
if (state->msg != NULL) {
|
if (state->msg != NULL) {
|
||||||
if (state->err != LZMA_MEM_ERROR)
|
if (state->err != LZMA_MEM_ERROR)
|
||||||
free(state->msg);
|
xmlFree(state->msg);
|
||||||
state->msg = NULL;
|
state->msg = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +106,7 @@ xz_error(xz_statep state, int err, const char *msg)
|
|||||||
|
|
||||||
/* construct error message with path */
|
/* construct error message with path */
|
||||||
if ((state->msg =
|
if ((state->msg =
|
||||||
malloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
|
xmlMalloc(strlen(state->path) + strlen(msg) + 3)) == NULL) {
|
||||||
state->err = LZMA_MEM_ERROR;
|
state->err = LZMA_MEM_ERROR;
|
||||||
state->msg = (char *) "out of memory";
|
state->msg = (char *) "out of memory";
|
||||||
return;
|
return;
|
||||||
@@ -137,17 +139,18 @@ xz_open(const char *path, int fd, const char *mode ATTRIBUTE_UNUSED)
|
|||||||
xz_statep state;
|
xz_statep state;
|
||||||
|
|
||||||
/* allocate xzFile structure to return */
|
/* allocate xzFile structure to return */
|
||||||
state = malloc(sizeof(xz_state));
|
state = xmlMalloc(sizeof(xz_state));
|
||||||
if (state == NULL)
|
if (state == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
state->size = 0; /* no buffers allocated yet */
|
state->size = 0; /* no buffers allocated yet */
|
||||||
state->want = BUFSIZ; /* requested buffer size */
|
state->want = BUFSIZ; /* requested buffer size */
|
||||||
state->msg = NULL; /* no error message yet */
|
state->msg = NULL; /* no error message yet */
|
||||||
|
state->init = 0; /* initialization of zlib data */
|
||||||
|
|
||||||
/* save the path name for error messages */
|
/* save the path name for error messages */
|
||||||
state->path = malloc(strlen(path) + 1);
|
state->path = xmlMalloc(strlen(path) + 1);
|
||||||
if (state->path == NULL) {
|
if (state->path == NULL) {
|
||||||
free(state);
|
xmlFree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
strcpy(state->path, path);
|
strcpy(state->path, path);
|
||||||
@@ -162,8 +165,8 @@ xz_open(const char *path, int fd, const char *mode ATTRIBUTE_UNUSED)
|
|||||||
#endif
|
#endif
|
||||||
O_RDONLY, 0666);
|
O_RDONLY, 0666);
|
||||||
if (state->fd == -1) {
|
if (state->fd == -1) {
|
||||||
free(state->path);
|
xmlFree(state->path);
|
||||||
free(state);
|
xmlFree(state);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,11 +194,11 @@ __libxml2_xzdopen(int fd, const char *mode)
|
|||||||
char *path; /* identifier for error messages */
|
char *path; /* identifier for error messages */
|
||||||
xzFile xz;
|
xzFile xz;
|
||||||
|
|
||||||
if (fd == -1 || (path = malloc(7 + 3 * sizeof(int))) == NULL)
|
if (fd == -1 || (path = xmlMalloc(7 + 3 * sizeof(int))) == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
sprintf(path, "<fd:%d>", fd); /* for debugging */
|
sprintf(path, "<fd:%d>", fd); /* for debugging */
|
||||||
xz = xz_open(path, fd, mode);
|
xz = xz_open(path, fd, mode);
|
||||||
free(path);
|
xmlFree(path);
|
||||||
return xz;
|
return xz;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -270,7 +273,7 @@ is_format_lzma(xz_statep state)
|
|||||||
|
|
||||||
opt = filter.options;
|
opt = filter.options;
|
||||||
dict_size = opt->dict_size;
|
dict_size = opt->dict_size;
|
||||||
free(opt);
|
xmlFree(opt);
|
||||||
|
|
||||||
/* A hack to ditch tons of false positives: We allow only dictionary
|
/* A hack to ditch tons of false positives: We allow only dictionary
|
||||||
* sizes that are 2^n or 2^n + 2^(n-1) or UINT32_MAX. LZMA_Alone
|
* sizes that are 2^n or 2^n + 2^(n-1) or UINT32_MAX. LZMA_Alone
|
||||||
@@ -344,13 +347,13 @@ xz_head(xz_statep state)
|
|||||||
/* allocate read buffers and inflate memory */
|
/* allocate read buffers and inflate memory */
|
||||||
if (state->size == 0) {
|
if (state->size == 0) {
|
||||||
/* allocate buffers */
|
/* allocate buffers */
|
||||||
state->in = malloc(state->want);
|
state->in = xmlMalloc(state->want);
|
||||||
state->out = malloc(state->want << 1);
|
state->out = xmlMalloc(state->want << 1);
|
||||||
if (state->in == NULL || state->out == NULL) {
|
if (state->in == NULL || state->out == NULL) {
|
||||||
if (state->out != NULL)
|
if (state->out != NULL)
|
||||||
free(state->out);
|
xmlFree(state->out);
|
||||||
if (state->in != NULL)
|
if (state->in != NULL)
|
||||||
free(state->in);
|
xmlFree(state->in);
|
||||||
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -361,8 +364,8 @@ xz_head(xz_statep state)
|
|||||||
state->strm.avail_in = 0;
|
state->strm.avail_in = 0;
|
||||||
state->strm.next_in = NULL;
|
state->strm.next_in = NULL;
|
||||||
if (lzma_auto_decoder(&state->strm, UINT64_MAX, 0) != LZMA_OK) {
|
if (lzma_auto_decoder(&state->strm, UINT64_MAX, 0) != LZMA_OK) {
|
||||||
free(state->out);
|
xmlFree(state->out);
|
||||||
free(state->in);
|
xmlFree(state->in);
|
||||||
state->size = 0;
|
state->size = 0;
|
||||||
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -374,12 +377,15 @@ xz_head(xz_statep state)
|
|||||||
state->zstrm.opaque = Z_NULL;
|
state->zstrm.opaque = Z_NULL;
|
||||||
state->zstrm.avail_in = 0;
|
state->zstrm.avail_in = 0;
|
||||||
state->zstrm.next_in = Z_NULL;
|
state->zstrm.next_in = Z_NULL;
|
||||||
if (inflateInit2(&(state->zstrm), -15) != Z_OK) { /* raw inflate */
|
if (state->init == 0) {
|
||||||
free(state->out);
|
if (inflateInit2(&(state->zstrm), -15) != Z_OK) {/* raw inflate */
|
||||||
free(state->in);
|
xmlFree(state->out);
|
||||||
state->size = 0;
|
xmlFree(state->in);
|
||||||
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
state->size = 0;
|
||||||
return -1;
|
xz_error(state, LZMA_MEM_ERROR, "out of memory");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
state->init = 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -733,15 +739,17 @@ __libxml2_xzclose(xzFile file)
|
|||||||
/* free memory and close file */
|
/* free memory and close file */
|
||||||
if (state->size) {
|
if (state->size) {
|
||||||
lzma_end(&(state->strm));
|
lzma_end(&(state->strm));
|
||||||
#ifdef HAVE_LIBZ_H
|
#ifdef HAVE_ZLIB_H
|
||||||
inflateEnd(&(state->zstrm));
|
if (state->init == 1)
|
||||||
|
inflateEnd(&(state->zstrm));
|
||||||
|
state->init = 0;
|
||||||
#endif
|
#endif
|
||||||
free(state->out);
|
xmlFree(state->out);
|
||||||
free(state->in);
|
xmlFree(state->in);
|
||||||
}
|
}
|
||||||
free(state->path);
|
xmlFree(state->path);
|
||||||
ret = close(state->fd);
|
ret = close(state->fd);
|
||||||
free(state);
|
xmlFree(state);
|
||||||
return ret ? ret : LZMA_OK;
|
return ret ? ret : LZMA_OK;
|
||||||
}
|
}
|
||||||
#endif /* HAVE_LZMA_H */
|
#endif /* HAVE_LZMA_H */
|
||||||
|
|||||||
Reference in New Issue
Block a user