Lint cleanup.
(from_chars): Report out-of-range values more precisely. (off_from_chars): Do not allow negative offsets. (uid_from_chars): Allow negative uids.
This commit is contained in:
81
src/list.c
81
src/list.c
@@ -222,7 +222,7 @@ list_archive (void)
|
||||
}
|
||||
}
|
||||
if (multi_volume_option)
|
||||
assign_string (&save_name, NULL);
|
||||
assign_string (&save_name, 0);
|
||||
fputc ('\n', stdlis);
|
||||
fflush (stdlis);
|
||||
return;
|
||||
@@ -243,7 +243,7 @@ list_archive (void)
|
||||
skip_file (current_stat.st_size);
|
||||
|
||||
if (multi_volume_option)
|
||||
assign_string (&save_name, NULL);
|
||||
assign_string (&save_name, 0);
|
||||
}
|
||||
|
||||
/*-----------------------------------------------------------------------.
|
||||
@@ -262,7 +262,7 @@ list_archive (void)
|
||||
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. */
|
||||
@@ -293,7 +293,7 @@ read_header (void)
|
||||
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++);
|
||||
@@ -304,7 +304,7 @@ read_header (void)
|
||||
|
||||
/* 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]);
|
||||
@@ -313,9 +313,8 @@ read_header (void)
|
||||
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;
|
||||
|
||||
@@ -344,12 +343,12 @@ read_header (void)
|
||||
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 ();
|
||||
if (data_block == NULL)
|
||||
if (! data_block)
|
||||
{
|
||||
ERROR ((0, 0, _("Unexpected EOF on archive file")));
|
||||
break;
|
||||
@@ -540,7 +539,12 @@ from_chars (char const *where0, size_t digs, char const *type,
|
||||
do
|
||||
{
|
||||
if (value << LG_8 >> LG_8 != value)
|
||||
goto out_of_range;
|
||||
{
|
||||
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));
|
||||
@@ -563,7 +567,12 @@ from_chars (char const *where0, size_t digs, char const *type,
|
||||
&& (dig = base64_map[(unsigned char) *where]) < 64)
|
||||
{
|
||||
if (value << LG_64 >> LG_64 != value)
|
||||
goto out_of_range;
|
||||
{
|
||||
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++;
|
||||
}
|
||||
@@ -578,7 +587,7 @@ from_chars (char const *where0, size_t digs, char const *type,
|
||||
|
||||
if (!o)
|
||||
{
|
||||
o = clone_quoting_options ((struct quoting_options *) 0);
|
||||
o = clone_quoting_options (0);
|
||||
set_quoting_style (o, c_quoting_style);
|
||||
}
|
||||
|
||||
@@ -586,7 +595,7 @@ from_chars (char const *where0, size_t digs, char const *type,
|
||||
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));
|
||||
}
|
||||
|
||||
@@ -596,10 +605,22 @@ from_chars (char const *where0, size_t digs, char const *type,
|
||||
if (value <= (negative ? minus_minval : maxval))
|
||||
return negative ? -value : value;
|
||||
|
||||
out_of_range:
|
||||
if (type)
|
||||
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)));
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -651,8 +672,9 @@ mode_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));
|
||||
}
|
||||
|
||||
@@ -674,7 +696,8 @@ time_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));
|
||||
}
|
||||
|
||||
@@ -723,8 +746,8 @@ isotime (time_t time)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 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;
|
||||
@@ -796,7 +819,7 @@ void
|
||||
print_header (void)
|
||||
{
|
||||
char modes[11];
|
||||
char const *timestamp;
|
||||
char const *time_stamp;
|
||||
/* These hold formatted ints. */
|
||||
char uform[UINTMAX_STRSIZE_BOUND], gform[UINTMAX_STRSIZE_BOUND];
|
||||
char *user, *group;
|
||||
@@ -885,7 +908,7 @@ print_header (void)
|
||||
|
||||
decode_mode (current_stat.st_mode, modes + 1);
|
||||
|
||||
/* Timestamp. */
|
||||
/* Time stamp. */
|
||||
|
||||
longie = current_stat.st_mtime;
|
||||
#if USE_OLD_CTIME
|
||||
@@ -893,16 +916,16 @@ print_header (void)
|
||||
char *ct = ctime (&longie);
|
||||
if (ct)
|
||||
{
|
||||
timestamp = ct + 4;
|
||||
time_stamp = ct + 4;
|
||||
for (ct += 16; ct[4] != '\n'; ct++)
|
||||
ct[0] = ct[4];
|
||||
ct[0] = '\0';
|
||||
}
|
||||
else
|
||||
timestamp = "??? ?? ??:?? ????";
|
||||
time_stamp = "??? ?? ??:?? ????";
|
||||
}
|
||||
#else
|
||||
timestamp = isotime (longie);
|
||||
time_stamp = isotime (longie);
|
||||
#endif
|
||||
|
||||
/* User and group names. */
|
||||
@@ -953,7 +976,7 @@ print_header (void)
|
||||
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)
|
||||
@@ -1079,7 +1102,7 @@ skip_file (off_t size)
|
||||
while (size > 0)
|
||||
{
|
||||
x = find_next_block ();
|
||||
if (x == NULL)
|
||||
if (! x)
|
||||
FATAL_ERROR ((0, 0, _("Unexpected EOF on archive file")));
|
||||
|
||||
set_next_block_after (x);
|
||||
|
||||
Reference in New Issue
Block a user