diff --git a/common.c b/common.c index f5e3073..334dc0b 100644 --- a/common.c +++ b/common.c @@ -5,16 +5,9 @@ #pragma mark UTILS -typedef struct { - lzma_block block; - lzma_filter filters[LZMA_FILTERS_MAX + 1]; -} block_wrapper_t; - FILE *gInFile = NULL; lzma_stream gStream = LZMA_STREAM_INIT; -lzma_check gCheck = LZMA_CHECK_NONE; - void die(const char *fmt, ...) { va_list args; @@ -36,32 +29,6 @@ char *xstrdup(const char *s) { return memcpy(r, s, len + 1); } -void *decode_block_start(off_t block_seek) { - if (fseeko(gInFile, block_seek, SEEK_SET) == -1) - die("Error seeking to block"); - - // Some memory in which to keep the discovered filters safe - block_wrapper_t *bw = malloc(sizeof(block_wrapper_t)); - bw->block = (lzma_block){ .check = gCheck, .filters = bw->filters, - .version = 0 }; - - int b = fgetc(gInFile); - if (b == EOF || b == 0) - die("Error reading block size"); - bw->block.header_size = lzma_block_header_size_decode(b); - uint8_t hdrbuf[bw->block.header_size]; - hdrbuf[0] = (uint8_t)b; - if (fread(hdrbuf + 1, bw->block.header_size - 1, 1, gInFile) != 1) - die("Error reading block header"); - if (lzma_block_header_decode(&bw->block, NULL, hdrbuf) != LZMA_OK) - die("Error decoding file index block header"); - - if (lzma_block_decoder(&gStream, &bw->block) != LZMA_OK) - die("Error initializing file index stream"); - - return bw; -} - bool is_multi_header(const char *name) { size_t i = strlen(name); while (i != 0 && name[i - 1] != '/') @@ -82,6 +49,9 @@ static lzma_ret gFIBErr = LZMA_OK; static uint8_t gFIBInputBuf[CHUNKSIZE]; static size_t gMoved = 0; +static void *decode_file_index_start(off_t block_seek, lzma_check check); +static lzma_vli find_file_index(void **bdatap); + static char *read_file_index_name(void); static void read_file_index_make_space(void); static void read_file_index_data(void); @@ -109,7 +79,38 @@ void free_file_index(void) { gFileIndex = gLastFile = NULL; } -lzma_vli find_file_index(void **bdatap) { +typedef struct { + lzma_block block; + lzma_filter filters[LZMA_FILTERS_MAX + 1]; +} block_wrapper_t; + +static void *decode_file_index_start(off_t block_seek, lzma_check check) { + if (fseeko(gInFile, block_seek, SEEK_SET) == -1) + die("Error seeking to block"); + + // Some memory in which to keep the discovered filters safe + block_wrapper_t *bw = malloc(sizeof(block_wrapper_t)); + bw->block = (lzma_block){ .check = check, .filters = bw->filters, + .version = 0 }; + + int b = fgetc(gInFile); + if (b == EOF || b == 0) + die("Error reading block size"); + bw->block.header_size = lzma_block_header_size_decode(b); + uint8_t hdrbuf[bw->block.header_size]; + hdrbuf[0] = (uint8_t)b; + if (fread(hdrbuf + 1, bw->block.header_size - 1, 1, gInFile) != 1) + die("Error reading block header"); + if (lzma_block_header_decode(&bw->block, NULL, hdrbuf) != LZMA_OK) + die("Error decoding file index block header"); + + if (lzma_block_decoder(&gStream, &bw->block) != LZMA_OK) + die("Error initializing file index stream"); + + return bw; +} + +static lzma_vli find_file_index(void **bdatap) { if (!gIndex) decode_index(); @@ -119,7 +120,8 @@ 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"); - void *bdata = decode_block_start(iter.block.compressed_file_offset); + void *bdata = decode_file_index_start(iter.block.compressed_file_offset, + iter.stream.flags->check); gFileIndexBuf = malloc(gFIBSize); gStream.avail_out = gFIBSize; @@ -281,7 +283,6 @@ static void stream_footer(bw *b, lzma_stream_flags *flags) { if (lzma_stream_footer_decode(flags, ftr) != LZMA_OK) die("Error decoding stream footer"); - gCheck = flags->check; // FIXME: multiple streams } static lzma_index *next_index(off_t *pos) { diff --git a/pixz.h b/pixz.h index 7e7b5fc..b7c7d61 100644 --- a/pixz.h +++ b/pixz.h @@ -50,8 +50,6 @@ uint64_t xle64dec(const uint8_t *d); void xle64enc(uint8_t *d, uint64_t n); size_t num_threads(void); -void *decode_block_start(off_t block_seek); - #pragma mark INDEX @@ -64,13 +62,9 @@ struct file_index_t { extern file_index_t *gFileIndex, *gLastFile; -// As discovered from footer -extern lzma_check gCheck; - bool is_multi_header(const char *name); bool decode_index(void); // true on success -lzma_vli find_file_index(void **bdatap); lzma_vli read_file_index(void); void dump_file_index(FILE *out, bool verbose); void free_file_index(void); diff --git a/read.c b/read.c index 592fc66..eb25bfd 100644 --- a/read.c +++ b/read.c @@ -28,6 +28,7 @@ typedef struct { size_t incap, outcap; size_t insize, outsize; off_t uoffset; // uncompressed offset + lzma_check check; } io_block_t; static void *block_create(void); @@ -69,8 +70,8 @@ static bool rbuf_cycle(lzma_stream *stream, bool start, size_t skip); static void rbuf_consume(size_t bytes); static void rbuf_dispatch(void); -static bool read_header(void); -static bool read_block(void); +static bool read_header(lzma_check *check); +static bool read_block(lzma_check check); static void read_streaming(lzma_block *block); static void read_index(void); static void read_footer(void); @@ -309,7 +310,7 @@ static void rbuf_dispatch(void) { } -static bool read_header(void) { +static bool read_header(lzma_check *check) { lzma_stream_flags stream_flags; rbuf_read_status st = rbuf_read(LZMA_STREAM_HEADER_SIZE); if (st == RBUF_EOF) @@ -321,14 +322,14 @@ static bool read_header(void) { die("Not an XZ file"); else if (err != LZMA_OK) die("Error decoding XZ header"); - gCheck = stream_flags.check; + *check = stream_flags.check; rbuf_consume(LZMA_STREAM_HEADER_SIZE); return true; } -static bool read_block(void) { +static bool read_block(lzma_check check) { lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_block block = { .filters = filters, .check = gCheck, .version = 0 }; + lzma_block block = { .filters = filters, .check = check, .version = 0 }; if (rbuf_read(1) != RBUF_FULL) die("Error reading block header size"); @@ -349,6 +350,7 @@ static bool read_block(void) { } else { block_capacity(gRbuf, 0, outsize); gRbuf->outsize = outsize; + gRbuf->check = check; if (rbuf_read(lzma_block_total_size(&block)) != RBUF_FULL) die("Error reading block contents"); @@ -441,9 +443,10 @@ static void read_footer(void) { static void read_thread_noindex(void) { bool empty = true; - while (read_header()) { + lzma_check check = LZMA_CHECK_NONE; + while (read_header(&check)) { empty = false; - while (read_block()) + while (read_block(check)) ; // pass read_index(); read_footer(); @@ -496,6 +499,7 @@ static void read_thread(void) { die("Error reading block contents"); offset += bsize; ib->uoffset = iter.block.uncompressed_file_offset; + ib->check = iter.stream.flags->check; pipeline_split(pi); } @@ -508,7 +512,8 @@ static void read_thread(void) { static void decode_thread(size_t thnum) { lzma_stream stream = LZMA_STREAM_INIT; lzma_filter filters[LZMA_FILTERS_MAX + 1]; - lzma_block block = { .filters = filters, .check = gCheck, .version = 0 }; + lzma_block block = { .filters = filters, .check = LZMA_CHECK_NONE, + .version = 0 }; pipeline_item_t *pi; io_block_t *ib; @@ -517,7 +522,8 @@ static void decode_thread(size_t thnum) { ib = (io_block_t*)(pi->data); block.header_size = lzma_block_header_size_decode(*(ib->input)); - if (lzma_block_header_decode(&block, NULL, ib->input) != LZMA_OK) + block.check = ib->check; + if (lzma_block_header_decode(&block, NULL, ib->input) != LZMA_OK) die("Error decoding block header"); if (lzma_block_decoder(&stream, &block) != LZMA_OK) die("Error initializing block decode");