Skip to content

Commit f03a913

Browse files
committed
fsck: use parse_unsigned_from_buf() for parsing timestamp
In 5a99359 (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.
1 parent e5d3ce5 commit f03a913

2 files changed

Lines changed: 5 additions & 17 deletions

File tree

compat/posix.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,8 @@ char *gitdirname(char *);
253253
typedef uintmax_t timestamp_t;
254254
#define PRItime PRIuMAX
255255
#define parse_timestamp strtoumax
256+
#define parse_timestamp_from_buf(buf, len, ep, result) \
257+
parse_unsigned_from_buf((buf), (len), (ep), (result), TIME_MAX)
256258
#define TIME_MAX UINTMAX_MAX
257259
#define TIME_MIN 0
258260

fsck.c

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -858,28 +858,13 @@ static int verify_headers(const void *data, unsigned long size,
858858
FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
859859
}
860860

861-
static timestamp_t parse_timestamp_from_buf(const char **start, const char *end)
862-
{
863-
const char *p = *start;
864-
char buf[24]; /* big enough for 2^64 */
865-
size_t i = 0;
866-
867-
while (p < end && isdigit(*p)) {
868-
if (i >= ARRAY_SIZE(buf) - 1)
869-
return TIME_MAX;
870-
buf[i++] = *p++;
871-
}
872-
buf[i] = '\0';
873-
*start = p;
874-
return parse_timestamp(buf, NULL, 10);
875-
}
876-
877861
static int fsck_ident(const char **ident, const char *ident_end,
878862
const struct object_id *oid, enum object_type type,
879863
struct fsck_options *options)
880864
{
881865
const char *p = *ident;
882866
const char *nl;
867+
timestamp_t timestamp;
883868

884869
nl = memchr(p, '\n', ident_end - p);
885870
if (!nl)
@@ -931,7 +916,8 @@ static int fsck_ident(const char **ident, const char *ident_end,
931916
"invalid author/committer line - bad date");
932917
if (*p == '0' && p[1] != ' ')
933918
return report(options, oid, type, FSCK_MSG_ZERO_PADDED_DATE, "invalid author/committer line - zero-padded date");
934-
if (date_overflows(parse_timestamp_from_buf(&p, ident_end)))
919+
if (!parse_timestamp_from_buf(p, ident_end - p, &p, &timestamp) ||
920+
date_overflows(timestamp))
935921
return report(options, oid, type, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
936922
if (*p != ' ')
937923
return report(options, oid, type, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");

0 commit comments

Comments
 (0)