help-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Help-tar] Re: Can't extract - get "Archive contains obsolescent base-64


From: Paul Eggert
Subject: [Help-tar] Re: Can't extract - get "Archive contains obsolescent base-64 headers"
Date: Thu, 03 Feb 2005 17:55:58 -0800
User-agent: Gnus/5.1006 (Gnus v5.10.6) Emacs/21.3 (gnu/linux)

Alexis Huxley <address@hidden> writes:

>     where0=0x807b694 
> "+¯#BiSQ)\032?;]\tÊØOPõ$\214Hº\031B\207\026YŸ>address@hidden", digs=8, 
> type=0x0, minus_minval=0, maxval=2147483647, 

Ah, OK, this appears to be coming from a part of the file that is
later than the hexdump you sent originally.  Tar is trying to validate
the checksum of the header, and the checksum is the bogus string shown
above.

This indeed looks like your archive is corrupted.  Perhaps you can
search for that exact string in your archive, and see what the data
looks like in that neighborhood.  Most likely it isn't proper tar
format, either because of a data error there, or (this is far less
likely, due to checksums) a data error in the header for the previous
file, which caused the size calculations to go wrong for the previous
file.

If it's just one isolated problem, possibly you can repair it with a
binary editor, but I should warn you that the odds are against you.

That "Archive contains obsolescent base-64 headers" message that you
got was bogus, though.  I installed the following patch.  Thanks
for reporting the problem.

2005-02-03  Paul Eggert  <address@hidden>

        * src/list.c (from_header): New arg OCTAL_ONLY, normally false.
        All uses changed.  Fix typo that sometimes suppressed all "Archive
        contains obsolescent base-64 headers" warnings, not just the first
        one.
        (tar_checksum): Accept only octal checksums, since they aren't
        supposed to overflow into weird formats.

Index: src/list.c
===================================================================
RCS file: /cvsroot/tar/tar/src/list.c,v
retrieving revision 1.83
diff -b -p -u -r1.83 list.c
--- src/list.c  4 Feb 2005 01:42:33 -0000       1.83
+++ src/list.c  4 Feb 2005 01:51:44 -0000
@@ -37,7 +37,7 @@ size_t recent_long_name_blocks;       /* numbe
 size_t recent_long_link_blocks;        /* likewise, for long link */
 
 static uintmax_t from_header (const char *, size_t, const char *,
-                             uintmax_t, uintmax_t, bool);
+                             uintmax_t, uintmax_t, bool, bool);
 
 /* Base 64 digits; see Internet RFC 2045 Table 1.  */
 static char const base_64_digits[64] =
@@ -309,7 +309,7 @@ tar_checksum (union block *header, bool 
   parsed_sum = from_header (header->header.chksum,
                            sizeof header->header.chksum, 0,
                            (uintmax_t) 0,
-                           (uintmax_t) TYPE_MAXIMUM (int), silent);
+                           (uintmax_t) TYPE_MAXIMUM (int), true, silent);
   if (parsed_sum == (uintmax_t) -1)
     return HEADER_FAILURE;
 
@@ -619,14 +619,15 @@ decode_header (union block *header, stru
 }
 
 /* Convert buffer at WHERE0 of size DIGS from external format to
-   uintmax_t.  The data is of type TYPE.  The buffer must represent a
-   value in the range -MINUS_MINVAL through MAXVAL.  DIGS must be
-   positive. SILENT=true inhibits printing diagnostic messages.
-   Return -1 on error, diagnosing the error if TYPE is
-   nonzero. */
+   uintmax_t.  DIGS must be positive.  If TYPE is nonnull, the data
+   are of type TYPE.  The buffer must represent a value in the range
+   -MINUS_MINVAL through MAXVAL.  If OCTAL_ONLY, allow only octal
+   numbers instead of the other GNU extensions.  Return -1 on error,
+   diagnosing the error if TYPE is nonnull and if !SILENT.  */
 static uintmax_t
 from_header (char const *where0, size_t digs, char const *type,
-            uintmax_t minus_minval, uintmax_t maxval, bool silent)
+            uintmax_t minus_minval, uintmax_t maxval,
+            bool octal_only, bool silent)
 {
   uintmax_t value;
   char const *where = where0;
@@ -716,19 +717,24 @@ from_header (char const *where0, size_t 
          return -1;
        }
     }
+  else if (octal_only)
+    {
+      /* Suppress the following extensions.  */
+    }
   else if (*where == '-' || *where == '+')
     {
       /* Parse base-64 output produced only by tar test versions
         1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
         Support for this will be withdrawn in future releases.  */
       int dig;
-      static int warned_once;
+      if (!silent)
+       {
+         static bool warned_once;
       if (! warned_once)
        {
-         warned_once = 1;
-         if (!silent)
-           WARN ((0, 0,
-                  _("Archive contains obsolescent base-64 headers")));
+             warned_once = true;
+             WARN ((0, 0, _("Archive contains obsolescent base-64 headers")));
+           }
        }
       negative = *where++ == '-';
       while (where != lim
@@ -837,7 +843,7 @@ gid_from_header (const char *p, size_t s
   return from_header (p, s, "gid_t",
                      - (uintmax_t) TYPE_MINIMUM (gid_t),
                      (uintmax_t) TYPE_MAXIMUM (gid_t),
-                     false);
+                     false, false);
 }
 
 major_t
@@ -845,7 +851,7 @@ major_from_header (const char *p, size_t
 {
   return from_header (p, s, "major_t",
                      - (uintmax_t) TYPE_MINIMUM (major_t),
-                     (uintmax_t) TYPE_MAXIMUM (major_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (major_t), false, false);
 }
 
 minor_t
@@ -853,7 +859,7 @@ minor_from_header (const char *p, size_t
 {
   return from_header (p, s, "minor_t",
                      - (uintmax_t) TYPE_MINIMUM (minor_t),
-                     (uintmax_t) TYPE_MAXIMUM (minor_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (minor_t), false, false);
 }
 
 mode_t
@@ -862,7 +868,7 @@ mode_from_header (const char *p, size_t 
   /* Do not complain about unrecognized mode bits.  */
   unsigned u = from_header (p, s, "mode_t",
                            - (uintmax_t) TYPE_MINIMUM (mode_t),
-                           TYPE_MAXIMUM (uintmax_t), false);
+                           TYPE_MAXIMUM (uintmax_t), false, false);
   return ((u & TSUID ? S_ISUID : 0)
          | (u & TSGID ? S_ISGID : 0)
          | (u & TSVTX ? S_ISVTX : 0)
@@ -883,14 +889,14 @@ off_from_header (const char *p, size_t s
   /* Negative offsets are not allowed in tar files, so invoke
      from_header with minimum value 0, not TYPE_MINIMUM (off_t).  */
   return from_header (p, s, "off_t", (uintmax_t) 0,
-                     (uintmax_t) TYPE_MAXIMUM (off_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (off_t), false, false);
 }
 
 size_t
 size_from_header (const char *p, size_t s)
 {
   return from_header (p, s, "size_t", (uintmax_t) 0,
-                     (uintmax_t) TYPE_MAXIMUM (size_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (size_t), false, false);
 }
 
 time_t
@@ -898,7 +904,7 @@ time_from_header (const char *p, size_t 
 {
   return from_header (p, s, "time_t",
                      - (uintmax_t) TYPE_MINIMUM (time_t),
-                     (uintmax_t) TYPE_MAXIMUM (time_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (time_t), false, false);
 }
 
 uid_t
@@ -906,14 +912,14 @@ uid_from_header (const char *p, size_t s
 {
   return from_header (p, s, "uid_t",
                      - (uintmax_t) TYPE_MINIMUM (uid_t),
-                     (uintmax_t) TYPE_MAXIMUM (uid_t), false);
+                     (uintmax_t) TYPE_MAXIMUM (uid_t), false, false);
 }
 
 uintmax_t
 uintmax_from_header (const char *p, size_t s)
 {
   return from_header (p, s, "uintmax_t", (uintmax_t) 0,
-                     TYPE_MAXIMUM (uintmax_t), false);
+                     TYPE_MAXIMUM (uintmax_t), false, false);
 }
 
 
@@ -1109,7 +1115,7 @@ print_header (struct tar_stat_info *st, 
                                     sizeof current_header->header.uid, 0,
                                     (uintmax_t) 0,
                                     (uintmax_t) TYPE_MAXIMUM (uintmax_t),
-                                    false);
+                                    false, false);
          if (u != -1)
            user = STRINGIFY_BIGINT (u, uform);
          else
@@ -1132,7 +1138,7 @@ print_header (struct tar_stat_info *st, 
                                     sizeof current_header->header.gid, 0,
                                     (uintmax_t) 0,
                                     (uintmax_t) TYPE_MAXIMUM (uintmax_t),
-                                    false);
+                                    false, false);
          if (g != -1)
            group = STRINGIFY_BIGINT (g, gform);
          else




reply via email to

[Prev in Thread] Current Thread [Next in Thread]