(from_chars): Report out-of-range values more precisely.
(off_from_chars): Do not allow negative offsets.
(uid_from_chars): Allow negative uids.
}
}
if (multi_volume_option)
}
}
if (multi_volume_option)
- assign_string (&save_name, NULL);
+ assign_string (&save_name, 0);
fputc ('\n', stdlis);
fflush (stdlis);
return;
fputc ('\n', stdlis);
fflush (stdlis);
return;
skip_file (current_stat.st_size);
if (multi_volume_option)
skip_file (current_stat.st_size);
if (multi_volume_option)
- assign_string (&save_name, NULL);
+ assign_string (&save_name, 0);
}
/*-----------------------------------------------------------------------.
}
/*-----------------------------------------------------------------------.
bytes in the header as type char. I think the type char was unsigned
on the PDP-11, but it's signed on the Next and Sun. It looks like the
sources to BSD tar were never changed to compute the checksum
bytes in the header as type char. I think the type char was unsigned
on the PDP-11, but it's signed on the Next and Sun. It looks like the
sources to BSD tar were never changed to compute the checksum
- currectly, so both the Sun and Next add the bytes of the header as
+ correctly, so both the Sun and Next add the bytes of the header as
signed chars. This doesn't cause a problem until you get a file with
a name containing characters with the high bit set. So read_header
computes two checksums -- signed and unsigned. */
signed chars. This doesn't cause a problem until you get a file with
a name containing characters with the high bit set. So read_header
computes two checksums -- signed and unsigned. */
unsigned_sum = 0;
signed_sum = 0;
p = header->buffer;
unsigned_sum = 0;
signed_sum = 0;
p = header->buffer;
- for (i = sizeof (*header); i-- != 0;)
+ for (i = sizeof *header; i-- != 0;)
{
unsigned_sum += (unsigned char) *p;
signed_sum += signed_char (*p++);
{
unsigned_sum += (unsigned char) *p;
signed_sum += signed_char (*p++);
/* Adjust checksum to count the "chksum" field as blanks. */
/* Adjust checksum to count the "chksum" field as blanks. */
- for (i = sizeof (header->header.chksum); i-- != 0;)
+ for (i = sizeof header->header.chksum; i-- != 0;)
{
unsigned_sum -= (unsigned char) header->header.chksum[i];
signed_sum -= signed_char (header->header.chksum[i]);
{
unsigned_sum -= (unsigned char) header->header.chksum[i];
signed_sum -= signed_char (header->header.chksum[i]);
signed_sum += ' ' * sizeof header->header.chksum;
parsed_sum = from_chars (header->header.chksum,
signed_sum += ' ' * sizeof header->header.chksum;
parsed_sum = from_chars (header->header.chksum,
- sizeof header->header.chksum,
- (char *) 0, (uintmax_t) 0,
- (uintmax_t) TYPE_MAXIMUM (int));
+ sizeof header->header.chksum, 0,
+ (uintmax_t) 0, (uintmax_t) TYPE_MAXIMUM (int));
if (parsed_sum == (uintmax_t) -1)
return HEADER_FAILURE;
if (parsed_sum == (uintmax_t) -1)
return HEADER_FAILURE;
size = current_stat.st_size;
if (size != current_stat.st_size)
FATAL_ERROR ((0, 0, _("Memory exhausted")));
size = current_stat.st_size;
if (size != current_stat.st_size)
FATAL_ERROR ((0, 0, _("Memory exhausted")));
- bp = *longp = (char *) xmalloc (size);
+ bp = *longp = xmalloc (size);
for (; size > 0; size -= written)
{
data_block = find_next_block ();
for (; size > 0; size -= written)
{
data_block = find_next_block ();
- if (data_block == NULL)
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
break;
{
ERROR ((0, 0, _("Unexpected EOF on archive file")));
break;
do
{
if (value << LG_8 >> LG_8 != value)
do
{
if (value << LG_8 >> LG_8 != value)
+ {
+ ERROR ((0, 0,
+ _("Archive octal string `%.*s' is out of %s range"),
+ (int) digs, where0, type));
+ return -1;
+ }
value = (value << LG_8) | (*where++ - '0');
}
while (where != lim && ISODIGIT (*where));
value = (value << LG_8) | (*where++ - '0');
}
while (where != lim && ISODIGIT (*where));
&& (dig = base64_map[(unsigned char) *where]) < 64)
{
if (value << LG_64 >> LG_64 != value)
&& (dig = base64_map[(unsigned char) *where]) < 64)
{
if (value << LG_64 >> LG_64 != value)
+ {
+ ERROR ((0, 0,
+ _("Archive signed base 64 string `%.*s' is out of %s range"),
+ (int) digs, where0, type));
+ return -1;
+ }
value = (value << LG_64) | dig;
where++;
}
value = (value << LG_64) | dig;
where++;
}
- o = clone_quoting_options ((struct quoting_options *) 0);
+ o = clone_quoting_options (0);
set_quoting_style (o, c_quoting_style);
}
set_quoting_style (o, c_quoting_style);
}
lim--;
quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
ERROR ((0, 0,
lim--;
quotearg_buffer (buf, sizeof buf, where0, lim - where, o);
ERROR ((0, 0,
- _("Header contains `%.*s' where numeric %s value expected"),
+ _("Archive contains `%.*s' where numeric %s value expected"),
(int) sizeof buf, buf, type));
}
(int) sizeof buf, buf, type));
}
if (value <= (negative ? minus_minval : maxval))
return negative ? -value : value;
if (value <= (negative ? minus_minval : maxval))
return negative ? -value : value;
- ERROR ((0, 0, _("Numeric value `%.*s' is out of range for %s"),
- (int) digs, where0, type));
+ {
+ char minval_buf[UINTMAX_STRSIZE_BOUND + 1];
+ char maxval_buf[UINTMAX_STRSIZE_BOUND];
+ char value_buf[UINTMAX_STRSIZE_BOUND + 1];
+ char *minval_string = STRINGIFY_BIGINT (minus_minval, minval_buf + 1);
+ char *value_string = STRINGIFY_BIGINT (value, value_buf + 1);
+ if (negative)
+ *--value_string = '-';
+ if (minus_minval)
+ *--minval_string = '-';
+ ERROR ((0, 0, _("Archive value %s is out of %s range %s..%s"),
+ value_string, type,
+ minval_string, STRINGIFY_BIGINT (maxval, maxval_buf)));
+ }
+
off_t
off_from_chars (const char *p, size_t s)
{
off_t
off_from_chars (const char *p, size_t s)
{
- return from_chars (p, s, "off_t",
- - (uintmax_t) TYPE_MINIMUM (off_t),
+ /* Negative offsets are not allowed in tar files, so invoke
+ from_chars with minimum value 0, not TYPE_MINIMUM (off_t). */
+ return from_chars (p, s, "off_t", (uintmax_t) 0,
(uintmax_t) TYPE_MAXIMUM (off_t));
}
(uintmax_t) TYPE_MAXIMUM (off_t));
}
uid_t
uid_from_chars (const char *p, size_t s)
{
uid_t
uid_from_chars (const char *p, size_t s)
{
- return from_chars (p, s, "uid_t", (uintmax_t) 0,
+ return from_chars (p, s, "uid_t",
+ - (uintmax_t) TYPE_MINIMUM (uid_t),
(uintmax_t) TYPE_MAXIMUM (uid_t));
}
(uintmax_t) TYPE_MAXIMUM (uid_t));
}
- /* The timestamp cannot be broken down, most likely because it
- is a huge timestamp. Convert it as an integer,
+ /* The time stamp cannot be broken down, most likely because it
+ is out of range. Convert it as an integer,
right-adjusted in a field with the same width as the usual
19-byte 4-year ISO time format. */
uintmax_t abstime = time < 0 ? - (uintmax_t) time : time;
right-adjusted in a field with the same width as the usual
19-byte 4-year ISO time format. */
uintmax_t abstime = time < 0 ? - (uintmax_t) time : time;
print_header (void)
{
char modes[11];
print_header (void)
{
char modes[11];
+ char const *time_stamp;
/* These hold formatted ints. */
char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
char *user, *group;
/* These hold formatted ints. */
char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
char *user, *group;
decode_mode (current_stat.st_mode, modes + 1);
decode_mode (current_stat.st_mode, modes + 1);
longie = current_stat.st_mtime;
#if USE_OLD_CTIME
longie = current_stat.st_mtime;
#if USE_OLD_CTIME
char *ct = ctime (&longie);
if (ct)
{
char *ct = ctime (&longie);
if (ct)
{
for (ct += 16; ct[4] != '\n'; ct++)
ct[0] = ct[4];
ct[0] = '\0';
}
else
for (ct += 16; ct[4] != '\n'; ct++)
ct[0] = ct[4];
ct[0] = '\0';
}
else
- timestamp = "??? ?? ??:?? ????";
+ time_stamp = "??? ?? ??:?? ????";
- timestamp = isotime (longie);
+ time_stamp = isotime (longie);
#endif
/* User and group names. */
#endif
/* User and group names. */
ugswidth = pad;
fprintf (stdlis, "%s %s/%s %*s%s %s",
ugswidth = pad;
fprintf (stdlis, "%s %s/%s %*s%s %s",
- modes, user, group, ugswidth - pad, "", size, timestamp);
+ modes, user, group, ugswidth - pad, "", size, time_stamp);
name = quote_copy_string (current_file_name);
if (name)
name = quote_copy_string (current_file_name);
if (name)
while (size > 0)
{
x = find_next_block ();
while (size > 0)
{
x = find_next_block ();
FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
set_next_block_after (x);
FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
set_next_block_after (x);