(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.
This commit is contained in:
Paul Eggert
2005-02-04 01:52:20 +00:00
parent 9c2f942930
commit 8f0112cb23

View File

@@ -37,7 +37,7 @@ size_t recent_long_name_blocks; /* number of blocks in recent_long_name */
size_t recent_long_link_blocks; /* likewise, for long link */ size_t recent_long_link_blocks; /* likewise, for long link */
static uintmax_t from_header (const char *, size_t, const char *, 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. */ /* Base 64 digits; see Internet RFC 2045 Table 1. */
static char const base_64_digits[64] = static char const base_64_digits[64] =
@@ -285,7 +285,7 @@ tar_checksum (union block *header, bool silent)
int recorded_sum; int recorded_sum;
uintmax_t parsed_sum; uintmax_t parsed_sum;
char *p; char *p;
p = header->buffer; p = header->buffer;
for (i = sizeof *header; i-- != 0;) for (i = sizeof *header; i-- != 0;)
{ {
@@ -309,12 +309,12 @@ tar_checksum (union block *header, bool silent)
parsed_sum = from_header (header->header.chksum, parsed_sum = from_header (header->header.chksum,
sizeof header->header.chksum, 0, sizeof header->header.chksum, 0,
(uintmax_t) 0, (uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (int), silent); (uintmax_t) TYPE_MAXIMUM (int), true, silent);
if (parsed_sum == (uintmax_t) -1) if (parsed_sum == (uintmax_t) -1)
return HEADER_FAILURE; return HEADER_FAILURE;
recorded_sum = parsed_sum; recorded_sum = parsed_sum;
if (unsigned_sum != recorded_sum && signed_sum != recorded_sum) if (unsigned_sum != recorded_sum && signed_sum != recorded_sum)
return HEADER_FAILURE; return HEADER_FAILURE;
@@ -350,7 +350,7 @@ read_header (bool raw_extended_headers)
while (1) while (1)
{ {
enum read_header status; enum read_header status;
header = find_next_block (); header = find_next_block ();
current_header = header; current_header = header;
if (!header) if (!header)
@@ -381,7 +381,7 @@ read_header (bool raw_extended_headers)
size = name_size + BLOCKSIZE; size = name_size + BLOCKSIZE;
if (n) if (n)
size += BLOCKSIZE - n; size += BLOCKSIZE - n;
if (name_size != current_stat_info.stat.st_size if (name_size != current_stat_info.stat.st_size
|| size < name_size) || size < name_size)
xalloc_die (); xalloc_die ();
@@ -619,14 +619,15 @@ decode_header (union block *header, struct tar_stat_info *stat_info,
} }
/* Convert buffer at WHERE0 of size DIGS from external format to /* Convert buffer at WHERE0 of size DIGS from external format to
uintmax_t. The data is of type TYPE. The buffer must represent a uintmax_t. DIGS must be positive. If TYPE is nonnull, the data
value in the range -MINUS_MINVAL through MAXVAL. DIGS must be are of type TYPE. The buffer must represent a value in the range
positive. SILENT=true inhibits printing diagnostic messages. -MINUS_MINVAL through MAXVAL. If OCTAL_ONLY, allow only octal
Return -1 on error, diagnosing the error if TYPE is numbers instead of the other GNU extensions. Return -1 on error,
nonzero. */ diagnosing the error if TYPE is nonnull and if !SILENT. */
static uintmax_t static uintmax_t
from_header (char const *where0, size_t digs, char const *type, 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; uintmax_t value;
char const *where = where0; char const *where = where0;
@@ -716,19 +717,24 @@ from_header (char const *where0, size_t digs, char const *type,
return -1; return -1;
} }
} }
else if (octal_only)
{
/* Suppress the following extensions. */
}
else if (*where == '-' || *where == '+') else if (*where == '-' || *where == '+')
{ {
/* Parse base-64 output produced only by tar test versions /* Parse base-64 output produced only by tar test versions
1.13.6 (1999-08-11) through 1.13.11 (1999-08-23). 1.13.6 (1999-08-11) through 1.13.11 (1999-08-23).
Support for this will be withdrawn in future releases. */ Support for this will be withdrawn in future releases. */
int dig; int dig;
static int warned_once; if (!silent)
if (! warned_once)
{ {
warned_once = 1; static bool warned_once;
if (!silent) if (! warned_once)
WARN ((0, 0, {
_("Archive contains obsolescent base-64 headers"))); warned_once = true;
WARN ((0, 0, _("Archive contains obsolescent base-64 headers")));
}
} }
negative = *where++ == '-'; negative = *where++ == '-';
while (where != lim while (where != lim
@@ -837,7 +843,7 @@ gid_from_header (const char *p, size_t s)
return from_header (p, s, "gid_t", return from_header (p, s, "gid_t",
- (uintmax_t) TYPE_MINIMUM (gid_t), - (uintmax_t) TYPE_MINIMUM (gid_t),
(uintmax_t) TYPE_MAXIMUM (gid_t), (uintmax_t) TYPE_MAXIMUM (gid_t),
false); false, false);
} }
major_t major_t
@@ -845,7 +851,7 @@ major_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "major_t", return from_header (p, s, "major_t",
- (uintmax_t) TYPE_MINIMUM (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 minor_t
@@ -853,7 +859,7 @@ minor_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "minor_t", return from_header (p, s, "minor_t",
- (uintmax_t) TYPE_MINIMUM (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 mode_t
@@ -862,7 +868,7 @@ mode_from_header (const char *p, size_t s)
/* Do not complain about unrecognized mode bits. */ /* Do not complain about unrecognized mode bits. */
unsigned u = from_header (p, s, "mode_t", unsigned u = from_header (p, s, "mode_t",
- (uintmax_t) TYPE_MINIMUM (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) return ((u & TSUID ? S_ISUID : 0)
| (u & TSGID ? S_ISGID : 0) | (u & TSGID ? S_ISGID : 0)
| (u & TSVTX ? S_ISVTX : 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 /* Negative offsets are not allowed in tar files, so invoke
from_header with minimum value 0, not TYPE_MINIMUM (off_t). */ from_header with minimum value 0, not TYPE_MINIMUM (off_t). */
return from_header (p, s, "off_t", (uintmax_t) 0, 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_t
size_from_header (const char *p, size_t s) size_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "size_t", (uintmax_t) 0, 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 time_t
@@ -898,7 +904,7 @@ time_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "time_t", return from_header (p, s, "time_t",
- (uintmax_t) TYPE_MINIMUM (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 uid_t
@@ -906,14 +912,14 @@ uid_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "uid_t", return from_header (p, s, "uid_t",
- (uintmax_t) TYPE_MINIMUM (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_t
uintmax_from_header (const char *p, size_t s) uintmax_from_header (const char *p, size_t s)
{ {
return from_header (p, s, "uintmax_t", (uintmax_t) 0, 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, off_t block_ordinal)
sizeof current_header->header.uid, 0, sizeof current_header->header.uid, 0,
(uintmax_t) 0, (uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (uintmax_t), (uintmax_t) TYPE_MAXIMUM (uintmax_t),
false); false, false);
if (u != -1) if (u != -1)
user = STRINGIFY_BIGINT (u, uform); user = STRINGIFY_BIGINT (u, uform);
else else
@@ -1132,7 +1138,7 @@ print_header (struct tar_stat_info *st, off_t block_ordinal)
sizeof current_header->header.gid, 0, sizeof current_header->header.gid, 0,
(uintmax_t) 0, (uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (uintmax_t), (uintmax_t) TYPE_MAXIMUM (uintmax_t),
false); false, false);
if (g != -1) if (g != -1)
group = STRINGIFY_BIGINT (g, gform); group = STRINGIFY_BIGINT (g, gform);
else else
@@ -1282,7 +1288,7 @@ skip_file (off_t size)
else else
seekable_archive = false; seekable_archive = false;
} }
while (size > 0) while (size > 0)
{ {
x = find_next_block (); x = find_next_block ();
@@ -1303,7 +1309,7 @@ skip_member (void)
{ {
char save_typeflag = current_header->header.typeflag; char save_typeflag = current_header->header.typeflag;
set_next_block_after (current_header); set_next_block_after (current_header);
assign_string (&save_name, current_stat_info.file_name); assign_string (&save_name, current_stat_info.file_name);
if (current_stat_info.is_sparse) if (current_stat_info.is_sparse)