From: Tim Kientzle Date: Sun, 25 Jul 2010 01:16:30 +0000 (-0400) Subject: Instead of trying a read-ahead after each filter stage, X-Git-Tag: v3.0.0a~909 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80e58628a9870f8dbd77a240ea56ed5c616cd12b;p=thirdparty%2Flibarchive.git Instead of trying a read-ahead after each filter stage, just do it once after the full pipeline is built. In particular, this catches errors on uncompressed input at open time. Also, if any filter stage fails to initialize, clean up the entire pipeline immediately. SVN-Revision: 2540 --- diff --git a/libarchive/archive_read.c b/libarchive/archive_read.c index 81d1abcfb..2d553076b 100644 --- a/libarchive/archive_read.c +++ b/libarchive/archive_read.c @@ -398,6 +398,13 @@ build_stream(struct archive_read *a) /* If no bidder, we're done. */ if (best_bidder == NULL) { + /* Verify the filter by asking it for some data. */ + __archive_read_filter_ahead(a->filter, 1, &avail); + if (avail < 0) { + close_filters(a); + free_filters(a); + return (ARCHIVE_FATAL); + } a->archive.compression_name = a->filter->name; a->archive.compression_code = a->filter->code; return (ARCHIVE_OK); @@ -410,15 +417,9 @@ build_stream(struct archive_read *a) filter->bidder = best_bidder; filter->archive = a; filter->upstream = a->filter; - r = (best_bidder->init)(filter); - if (r != ARCHIVE_OK) { - 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) { + r = (best_bidder->init)(a->filter); + if (r != ARCHIVE_OK) { close_filters(a); free_filters(a); return (ARCHIVE_FATAL); @@ -462,7 +463,8 @@ _archive_read_next_header2(struct archive *_a, struct archive_entry *entry) if (a->archive.state == ARCHIVE_STATE_DATA) { ret = archive_read_data_skip(&a->archive); if (ret == ARCHIVE_EOF) { - archive_set_error(&a->archive, EIO, "Premature end-of-file."); + archive_set_error(&a->archive, EIO, + "Premature end-of-file."); a->archive.state = ARCHIVE_STATE_FATAL; return (ARCHIVE_FATAL); }