Date: Sat, 23 Jan 2010 07:52:13 +0000 (UTC) From: Tim Kientzle <kientzle@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r202868 - head/lib/libarchive Message-ID: <201001230752.o0N7qD5Q040482@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kientzle Date: Sat Jan 23 07:52:13 2010 New Revision: 202868 URL: http://svn.freebsd.org/changeset/base/202868 Log: Fix a memory leak when a filter fails to initialize. Modified: head/lib/libarchive/archive_read.c Modified: head/lib/libarchive/archive_read.c ============================================================================== --- head/lib/libarchive/archive_read.c Sat Jan 23 06:42:47 2010 (r202867) +++ head/lib/libarchive/archive_read.c Sat Jan 23 07:52:13 2010 (r202868) @@ -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. */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201001230752.o0N7qD5Q040482>