]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fsck: use parse_unsigned_from_buf() for parsing timestamp
authorJeff King <peff@peff.net>
Sun, 30 Nov 2025 13:16:02 +0000 (08:16 -0500)
committerJunio C Hamano <gitster@pobox.com>
Sun, 30 Nov 2025 18:03:43 +0000 (10:03 -0800)
In 5a993593b2 (fsck: avoid parse_timestamp() on buffer that isn't
NUL-terminated, 2025-11-18), we added a wrapper that copies the
timestamp into a buffer before calling parse_timestamp().

Now that we have a more robust helper for parsing from a buffer, we can
drop our wrapper and switch to that. We could just do so inline, but the
choice of "unsigned" vs "signed" depends on the typedef of timestamp_t.
So we'll wrap that in a macro that is defined alongside the rest of the
timestamp abstraction.

The resulting function is almost a drop-in replacement, but the new
interface means we need to hold the result in a separate timestamp_t,
rather than returning it directly from one function into the parameter
of another. The old one did still detect overflow errors by returning
TIME_MAX, since date_overflows() checks for that, but now we'll see it
more directly from the return of parse_timestamp_from_buf(). The
behavior should be the same.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
compat/posix.h
fsck.c

index 067a00f33b83f31ffabff5045c9bda1a9059dda2..d2dbc3e2a5e47fe5e21d2695de76264bd1d19f96 100644 (file)
@@ -253,6 +253,8 @@ char *gitdirname(char *);
 typedef uintmax_t timestamp_t;
 #define PRItime PRIuMAX
 #define parse_timestamp strtoumax
+#define parse_timestamp_from_buf(buf, len, ep, result) \
+       parse_unsigned_from_buf((buf), (len), (ep), (result), TIME_MAX)
 #define TIME_MAX UINTMAX_MAX
 #define TIME_MIN 0
 
diff --git a/fsck.c b/fsck.c
index 8e8083e7c6e42ab4356bd67602e61a367b207f79..68a23ae6280869b2dbcfeb4837f0d2f61af948c3 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -860,28 +860,13 @@ static int verify_headers(const void *data, unsigned long size,
                FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
 }
 
-static timestamp_t parse_timestamp_from_buf(const char **start, const char *end)
-{
-       const char *p = *start;
-       char buf[24]; /* big enough for 2^64 */
-       size_t i = 0;
-
-       while (p < end && isdigit(*p)) {
-               if (i >= ARRAY_SIZE(buf) - 1)
-                       return TIME_MAX;
-               buf[i++] = *p++;
-       }
-       buf[i] = '\0';
-       *start = p;
-       return parse_timestamp(buf, NULL, 10);
-}
-
 static int fsck_ident(const char **ident, const char *ident_end,
                      const struct object_id *oid, enum object_type type,
                      struct fsck_options *options)
 {
        const char *p = *ident;
        const char *nl;
+       timestamp_t timestamp;
 
        nl = memchr(p, '\n', ident_end - p);
        if (!nl)
@@ -933,7 +918,8 @@ static int fsck_ident(const char **ident, const char *ident_end,
                              "invalid author/committer line - bad date");
        if (*p == '0' && p[1] != ' ')
                return report(options, oid, type, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
-       if (date_overflows(parse_timestamp_from_buf(&p, ident_end)))
+       if (!parse_timestamp_from_buf(p, ident_end - p, &p, &timestamp) ||
+           date_overflows(timestamp))
                return report(options, oid, type, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
        if (*p != ' ')
                return report(options, oid, type, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");