Hello, gently ping. I rephrased the commit message (patch attached). Pavel
On Thursday, March 30, 2017 2:05:07 PM CEST Pavel Raiskup wrote: > Heuristic for guessing the archive/compression format works with > archive magic and tar_checksum() which depends on the first block > (BLOCKSIZE) of archive data in pre-fetched buffer. > > Very small files though (compressed size is smaller than > BLOCKSIZE) don't initialize a whole data block in buffer, so the > heuristic calculated with uninitialized data previously. In rare > situations compressed archives were marked as non-compressed, > which in turn caused extraction failure. > > * src/buffer.c (check_compressed_archive): Don't assume archives > smaller than BLOCKSIZE could be non-compressed, as tar header has > always has at least one block. > --- > src/buffer.c | 10 ++++++---- > 1 file changed, 6 insertions(+), 4 deletions(-) > > diff --git a/src/buffer.c b/src/buffer.c > index fb34834..f064d2a 100644 > --- a/src/buffer.c > +++ b/src/buffer.c > @@ -391,10 +391,12 @@ check_compressed_archive (bool *pshort) > /* Restore global values */ > read_full_records = sfr; > > - if ((strcmp (record_start->header.magic, TMAGIC) == 0 || > - strcmp (record_start->buffer + offsetof (struct posix_header, magic), > - OLDGNU_MAGIC) == 0) && > - tar_checksum (record_start, true) == HEADER_SUCCESS) > + if (record_start != record_end /* no files smaller than BLOCKSIZE */ > + && (strcmp (record_start->header.magic, TMAGIC) == 0 > + || strcmp (record_start->buffer + offsetof (struct posix_header, > + magic), > + OLDGNU_MAGIC) == 0) > + && tar_checksum (record_start, true) == HEADER_SUCCESS) > /* Probably a valid header */ > return ct_tar; > >
>From 3fe273c4ee7b0c29be6123cc5f46c02b3c6dd04a Mon Sep 17 00:00:00 2001 From: Pavel Raiskup <prais...@redhat.com> Date: Thu, 30 Mar 2017 13:30:15 +0200 Subject: [PATCH] Fix non-deterministic archive type detection Due to analysis of partly uninitialized read-ahead buffer (short_read call), we sometimes mistakenly classified very small compressed archives as non-compressed; which in turn caused extraction failure. * src/buffer.c (check_compressed_archive): Don't assume that archives smaller than BLOCKSIZE could be non-compressed, as tar header always has at least one block. --- src/buffer.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/buffer.c b/src/buffer.c index fb34834..f064d2a 100644 --- a/src/buffer.c +++ b/src/buffer.c @@ -391,10 +391,12 @@ check_compressed_archive (bool *pshort) /* Restore global values */ read_full_records = sfr; - if ((strcmp (record_start->header.magic, TMAGIC) == 0 || - strcmp (record_start->buffer + offsetof (struct posix_header, magic), - OLDGNU_MAGIC) == 0) && - tar_checksum (record_start, true) == HEADER_SUCCESS) + if (record_start != record_end /* no files smaller than BLOCKSIZE */ + && (strcmp (record_start->header.magic, TMAGIC) == 0 + || strcmp (record_start->buffer + offsetof (struct posix_header, + magic), + OLDGNU_MAGIC) == 0) + && tar_checksum (record_start, true) == HEADER_SUCCESS) /* Probably a valid header */ return ct_tar; -- 2.9.3