]> git.ipfire.org Git - thirdparty/tar.git/commitdiff
Adjust to Gnulib strftime changes for macOS
authorPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Nov 2025 09:05:05 +0000 (01:05 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Sat, 15 Nov 2025 23:10:48 +0000 (15:10 -0800)
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.

gnulib.modules
src/checkpoint.c

index 2640614d092df9d4871743e8009a7f9600b04a19..ede48729bd604a81d3fb0dc1a34fd53158da8abe 100644 (file)
@@ -49,7 +49,6 @@ file-has-acl
 fileblocks
 flexmember
 fnmatch-gnu
-fprintftime
 free-posix
 fseeko
 fstatat
index 903b8ce320db84ddeb42ed1de82f3058e2211358..a07a54eaa2733af215ae9aca6eae00f1555f4854 100644 (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;