From 267e538c5eedd99a436a542d45d3a9e0754298c8 Mon Sep 17 00:00:00 2001 From: Dave Vasilevsky Date: Sat, 10 Nov 2012 00:00:35 -0500 Subject: [PATCH] More file-index skipping fixes Don't detect file-index on multi-stream files, that usage is not supported. Handle multi-stream files correctly when using heuristic skipping. --- common.c | 3 +++ read.c | 26 ++++++++++++++------------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/common.c b/common.c index 8077541..0740d30 100644 --- a/common.c +++ b/common.c @@ -120,6 +120,9 @@ static lzma_vli find_file_index(void **bdatap) { lzma_vli loc = lzma_index_uncompressed_size(gIndex) - 1; if (lzma_index_iter_locate(&iter, loc)) die("Can't locate file index block"); + if (iter.stream.number != 1) + return 0; // Too many streams for one file index + void *bdata = decode_file_index_start(iter.block.compressed_file_offset, iter.stream.flags->check); diff --git a/read.c b/read.c index 1085e71..a496148 100644 --- a/read.c +++ b/read.c @@ -106,7 +106,6 @@ void pixz_read(bool verify, size_t nspecs, char **specs) { debug("want: %s", w->name); #endif - bool first = true; pipeline_create(block_create, block_free, gIndex ? read_thread : read_thread_noindex, decode_thread); if (verify && gFileIndexOffset) { @@ -155,27 +154,30 @@ void pixz_read(bool verify, size_t nspecs, char **specs) { if (w && w->name) die("File %s missing in archive", w->name); tar_write_last(); // write whatever's left - first = false; } if (!gExplicitFiles) { - bool tar = false; - bool all_sized = true; - bool skipping = false; + /* Heuristics for detecting pixz file index: + * - Input must be streaming (otherwise read_thread does this) + * - Data must look tar-like + * - Must have all sized blocks, followed by unsized file index */ + bool start = !gIndex && verify, + tar = false, all_sized = true, skipping = false; pipeline_item_t *pi; while ((pi = pipeline_merged())) { io_block_t *ib = (io_block_t*)(pi->data); - if (first) { - tar = taste_tar(ib); - first = false; - } if (skipping && ib->btype != BLOCK_CONTINUATION) { - die("File index heuristic failed, retry with -t flag"); + fprintf(stderr, + "Warning: File index heuristic failed, use -t flag.\n"); skipping = false; } - if (verify && !skipping && !first && tar && all_sized + if (!skipping && tar && !start && all_sized && ib->btype == BLOCK_UNSIZED && taste_file_index(ib)) skipping = true; + if (start) { + tar = taste_tar(ib); + start = false; + } if (ib->btype != BLOCK_SIZED) all_sized = false; @@ -541,7 +543,7 @@ static void read_thread(void) { offset += bsize; ib->uoffset = iter.block.uncompressed_file_offset; ib->check = iter.stream.flags->check; - ib->btype = BLOCK_SIZED; + ib->btype = BLOCK_SIZED; // Indexed blocks always sized pipeline_split(pi); }