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;