From owner-svn-src-all@FreeBSD.ORG Sat Jan 23 07:52:13 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 9E947106566C; Sat, 23 Jan 2010 07:52:13 +0000 (UTC) (envelope-from kientzle@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 751598FC14; Sat, 23 Jan 2010 07:52:13 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o0N7qDJ8040484; Sat, 23 Jan 2010 07:52:13 GMT (envelope-from kientzle@svn.freebsd.org) Received: (from kientzle@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o0N7qD5Q040482; Sat, 23 Jan 2010 07:52:13 GMT (envelope-from kientzle@svn.freebsd.org) Message-Id: <201001230752.o0N7qD5Q040482@svn.freebsd.org> From: Tim Kientzle Date: Sat, 23 Jan 2010 07:52:13 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r202868 - head/lib/libarchive X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 23 Jan 2010 07:52:13 -0000 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. */