From: Paul Eggert Date: Sat, 15 Nov 2025 09:05:05 +0000 (-0800) Subject: Adjust to Gnulib strftime changes for macOS X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=453d903de916a9f705398152cec9db369b7d7bb8;p=thirdparty%2Ftar.git 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. --- diff --git a/gnulib.modules b/gnulib.modules index 2640614d..ede48729 100644 --- a/gnulib.modules +++ b/gnulib.modules @@ -49,7 +49,6 @@ file-has-acl fileblocks flexmember fnmatch-gnu -fprintftime free-posix fseeko fstatat diff --git a/src/checkpoint.c b/src/checkpoint.c index 903b8ce3..a07a54ea 100644 --- a/src/checkpoint.c +++ b/src/checkpoint.c @@ -21,9 +21,7 @@ #include "common.h" #include - #include -#include #include #include @@ -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;