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

Reply via email to