mirror of
https://git.savannah.gnu.org/git/tar.git
synced 2026-08-21 16:56:06 +00:00
Fix unlikely problems with time overflow
Also, fix some rounding errors while we’re in the neighborhood. * src/buffer.c (duration_ns, compute_duration_ns): Rename from ‘duration’ and ‘compute_duration’, and count ns rather than s, to lessen rounding error. All uses changed. (compute_duration_ns): Work even if the clock moves backward and time_t is unsigned. (print_stats): Don’t worry about null or empty TEXT, as that cannot happen. Compare double to UINTMAX_MAX + 1.0, not to UINTMAX_MAX, so that the comparison is exact. Handle the unlikely case that numbytes >= UINTMAX_MAX. * src/tar.c (parse_opt): Treat -L hugenumber as effectively infinity rather than erroring out. Prefer ckd_add to checking overflow by hand.
This commit is contained in:
@@ -1083,7 +1083,7 @@ set_use_compress_program_option (const char *string, struct option_locus *loc)
|
||||
static void
|
||||
sigstat (int signo)
|
||||
{
|
||||
compute_duration ();
|
||||
compute_duration_ns ();
|
||||
print_total_stats ();
|
||||
#ifndef HAVE_SIGACTION
|
||||
signal (signo, sigstat);
|
||||
@@ -1688,13 +1688,24 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
uintmax_t u;
|
||||
char *p;
|
||||
|
||||
if (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES) != LONGINT_OK)
|
||||
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
|
||||
_("Invalid tape length")));
|
||||
if (p > arg && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
|
||||
tape_length_option = 1024 * (tarlong) u;
|
||||
else
|
||||
tape_length_option = (tarlong) u;
|
||||
switch (xstrtoumax (arg, &p, 10, &u, TAR_SIZE_SUFFIXES))
|
||||
{
|
||||
case LONGINT_OK:
|
||||
tape_length_option = u;
|
||||
if (arg < p && !strchr (TAR_SIZE_SUFFIXES, p[-1]))
|
||||
tape_length_option *= 1024;
|
||||
break;
|
||||
|
||||
case LONGINT_OVERFLOW:
|
||||
/* Treat enormous values as effectively infinity. */
|
||||
tape_length_option = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
|
||||
_("Invalid tape length")));
|
||||
}
|
||||
|
||||
multi_volume_option = true;
|
||||
}
|
||||
break;
|
||||
@@ -2102,10 +2113,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
uintmax_t u;
|
||||
|
||||
if (! (xstrtoumax (arg, NULL, 10, &u, TAR_SIZE_SUFFIXES) == LONGINT_OK
|
||||
&& u == (size_t) u))
|
||||
&& !ckd_add (&record_size, u, 0)))
|
||||
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
|
||||
_("Invalid record size")));
|
||||
record_size = u;
|
||||
if (record_size % BLOCKSIZE != 0)
|
||||
USAGE_ERROR ((0, 0, _("Record size must be a multiple of %d."),
|
||||
BLOCKSIZE));
|
||||
@@ -2151,10 +2161,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
{
|
||||
uintmax_t u;
|
||||
if (! (xstrtoumax (arg, 0, 10, &u, "") == LONGINT_OK
|
||||
&& u == (size_t) u))
|
||||
&& !ckd_add (&strip_name_components, u, 0)))
|
||||
USAGE_ERROR ((0, 0, "%s: %s", quotearg_colon (arg),
|
||||
_("Invalid number of elements")));
|
||||
strip_name_components = u;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user