Adjust to Gnulib strftime changes for macOS

Stop using the fprintftime module, as as with recent Gnulib changes
it breaks the build on macOS, and fixing this would drag in threading
libraries and macOS-specific libraries that are overkill for tar.
Instead, just use strftime; that’s good enough here and arguably
better in case someone attacks tar with a huge time format string.
* gnulib.modules: Remove fprintftime.
* src/checkpoint.c: Do not include fprintftime.
(format_checkpoint_string): Always output some useful info (a decimal
seconds count), even if localtime fails. Do not output more than
256 bytes of time info, as that’s likely a DoS attack.  Stick with
plain strftime, as fprintftime’s extra features are overkill here.
This commit is contained in:
Paul Eggert
2025-11-15 01:05:05 -08:00
parent 0521528cdf
commit 453d903de9
2 changed files with 19 additions and 7 deletions

View File

@@ -49,7 +49,6 @@ file-has-acl
fileblocks
flexmember
fnmatch-gnu
fprintftime
free-posix
fseeko
fstatat

View File

@@ -21,9 +21,7 @@
#include "common.h"
#include <wordsplit.h>
#include <flexmember.h>
#include <fprintftime.h>
#include <sys/ioctl.h>
#include <termios.h>
@@ -153,6 +151,9 @@ checkpoint_finish_compile (void)
}
}
/* Get the number of columns in the FP output stream.
FIXME: The rest of the code counts bytes, not columns,
so columns don't line up if multi-byte characters are output. */
static intmax_t
getwidth (FILE *fp)
{
@@ -304,11 +305,23 @@ format_checkpoint_string (FILE *fp, intmax_t len,
case 't':
{
struct timespec ts = current_timespec ();
const char *fmt = arg ? arg : "%c";
struct tm *tm = localtime (&ts.tv_sec);
len = add_printf (len,
(tm ? fprintftime (fp, fmt, tm, 0, ts.tv_nsec)
: fprintf (fp, "????""-??""-?? ??:??:??")));
char const *tmstr = NULL;
/* Keep BUF relatively small, as any text timestamp
not fitting into BUF is likely a DoS attack. */
char buf[max (SYSINT_BUFSIZE, 256)];
if (tm)
{
buf[0] = '\0';
char const *fmt = arg ? arg : "%c";
if (strftime (buf, sizeof buf, fmt, tm) != 0 || !buf[0])
tmstr = buf;
}
if (!tmstr)
tmstr = timetostr (ts.tv_sec, buf);
len = add_printf (len, fprintf (fp, "%s", tmstr));
}
break;