summaryrefslogtreecommitdiffstats
path: root/lib/libarchive
diff options
context:
space:
mode:
authorkientzle <kientzle@FreeBSD.org>2010-01-23 07:52:13 +0000
committerkientzle <kientzle@FreeBSD.org>2010-01-23 07:52:13 +0000
commit643a6f51c1d7cff9b6d3e3c3411c9344a8eab43e (patch)
tree0e002528c25b691cc569a8803787f4384c8b34a7 /lib/libarchive
parentc88be204c754239a8a19025fa8bee6f2c54eb282 (diff)
downloadFreeBSD-src-643a6f51c1d7cff9b6d3e3c3411c9344a8eab43e.zip
FreeBSD-src-643a6f51c1d7cff9b6d3e3c3411c9344a8eab43e.tar.gz
Fix a memory leak when a filter fails to initialize.
Diffstat (limited to 'lib/libarchive')
-rw-r--r--lib/libarchive/archive_read.c43
1 files changed, 27 insertions, 16 deletions
diff --git a/lib/libarchive/archive_read.c b/lib/libarchive/archive_read.c
index fd56dc6..91c5aa5 100644
--- a/lib/libarchive/archive_read.c
+++ b/lib/libarchive/archive_read.c
@@ -57,6 +57,7 @@ __FBSDID("$FreeBSD$");
static int build_stream(struct archive_read *);
static int choose_format(struct archive_read *);
+static int cleanup_filters(struct archive_read *);
static struct archive_vtable *archive_read_vtable(void);
static int _archive_read_close(struct archive *);
static int _archive_read_finish(struct archive *);
@@ -393,14 +394,13 @@ build_stream(struct archive_read *a)
free(filter);
return (r);
}
+ a->filter = filter;
/* Verify the filter by asking it for some data. */
__archive_read_filter_ahead(filter, 1, &avail);
if (avail < 0) {
- /* If the read failed, bail out now. */
- free(filter);
- return (avail);
+ cleanup_filters(a);
+ return (ARCHIVE_FATAL);
}
- a->filter = filter;
}
}
@@ -738,18 +738,10 @@ _archive_read_close(struct archive *_a)
/* TODO: Clean up the formatters. */
- /* Clean up the filter pipeline. */
- while (a->filter != NULL) {
- struct archive_read_filter *t = a->filter->upstream;
- if (a->filter->close != NULL) {
- r1 = (a->filter->close)(a->filter);
- if (r1 < r)
- r = r1;
- }
- free(a->filter->buffer);
- free(a->filter);
- a->filter = t;
- }
+ /* Release the filter objects. */
+ r1 = cleanup_filters(a);
+ if (r1 < r)
+ r = r1;
/* Release the bidder objects. */
n = sizeof(a->bidders)/sizeof(a->bidders[0]);
@@ -764,6 +756,25 @@ _archive_read_close(struct archive *_a)
return (r);
}
+static int
+cleanup_filters(struct archive_read *a)
+{
+ int r = ARCHIVE_OK;
+ /* Clean up the filter pipeline. */
+ while (a->filter != NULL) {
+ struct archive_read_filter *t = a->filter->upstream;
+ if (a->filter->close != NULL) {
+ int r1 = (a->filter->close)(a->filter);
+ if (r1 < r)
+ r = r1;
+ }
+ free(a->filter->buffer);
+ free(a->filter);
+ a->filter = t;
+ }
+ return r;
+}
+
/*
* Release memory and other resources.
*/
OpenPOWER on IntegriCloud