mirror of
https://github.com/git/git.git
synced 2026-01-09 17:46:37 +00:00
Merge branch 'jk/asan-bonanza'
Various issues detected by Asan have been corrected. * jk/asan-bonanza: t: enable ASan's strict_string_checks option fsck: avoid parse_timestamp() on buffer that isn't NUL-terminated fsck: remove redundant date timestamp check fsck: avoid strcspn() in fsck_ident() fsck: assert newline presence in fsck_ident() cache-tree: avoid strtol() on non-string buffer Makefile: turn on NO_MMAP when building with ASan pack-bitmap: handle name-hash lookups in incremental bitmaps compat/mmap: mark unused argument in git_munmap()
This commit is contained in:
71
fsck.c
71
fsck.c
@@ -860,31 +860,60 @@ static int verify_headers(const void *data, unsigned long size,
|
||||
FSCK_MSG_UNTERMINATED_HEADER, "unterminated header");
|
||||
}
|
||||
|
||||
static int fsck_ident(const char **ident,
|
||||
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;
|
||||
char *end;
|
||||
const char *nl;
|
||||
|
||||
*ident = strchrnul(*ident, '\n');
|
||||
if (**ident == '\n')
|
||||
(*ident)++;
|
||||
nl = memchr(p, '\n', ident_end - p);
|
||||
if (!nl)
|
||||
BUG("verify_headers() should have made sure we have a newline");
|
||||
*ident = nl + 1;
|
||||
|
||||
if (*p == '<')
|
||||
return report(options, oid, type, FSCK_MSG_MISSING_NAME_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
|
||||
p += strcspn(p, "<>\n");
|
||||
if (*p == '>')
|
||||
return report(options, oid, type, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name");
|
||||
if (*p != '<')
|
||||
return report(options, oid, type, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email");
|
||||
for (;;) {
|
||||
if (p >= ident_end || *p == '\n')
|
||||
return report(options, oid, type, FSCK_MSG_MISSING_EMAIL, "invalid author/committer line - missing email");
|
||||
if (*p == '>')
|
||||
return report(options, oid, type, FSCK_MSG_BAD_NAME, "invalid author/committer line - bad name");
|
||||
if (*p == '<')
|
||||
break; /* end of name, beginning of email */
|
||||
|
||||
/* otherwise, skip past arbitrary name char */
|
||||
p++;
|
||||
}
|
||||
if (p[-1] != ' ')
|
||||
return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_EMAIL, "invalid author/committer line - missing space before email");
|
||||
p++;
|
||||
p += strcspn(p, "<>\n");
|
||||
if (*p != '>')
|
||||
return report(options, oid, type, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email");
|
||||
p++;
|
||||
p++; /* skip past '<' we found */
|
||||
for (;;) {
|
||||
if (p >= ident_end || *p == '<' || *p == '\n')
|
||||
return report(options, oid, type, FSCK_MSG_BAD_EMAIL, "invalid author/committer line - bad email");
|
||||
if (*p == '>')
|
||||
break; /* end of email */
|
||||
|
||||
/* otherwise, skip past arbitrary email char */
|
||||
p++;
|
||||
}
|
||||
p++; /* skip past '>' we found */
|
||||
if (*p != ' ')
|
||||
return report(options, oid, type, FSCK_MSG_MISSING_SPACE_BEFORE_DATE, "invalid author/committer line - missing space before date");
|
||||
p++;
|
||||
@@ -904,11 +933,11 @@ static int fsck_ident(const char **ident,
|
||||
"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(p, &end, 10)))
|
||||
if (date_overflows(parse_timestamp_from_buf(&p, ident_end)))
|
||||
return report(options, oid, type, FSCK_MSG_BAD_DATE_OVERFLOW, "invalid author/committer line - date causes integer overflow");
|
||||
if ((end == p || *end != ' '))
|
||||
if (*p != ' ')
|
||||
return report(options, oid, type, FSCK_MSG_BAD_DATE, "invalid author/committer line - bad date");
|
||||
p = end + 1;
|
||||
p++;
|
||||
if ((*p != '+' && *p != '-') ||
|
||||
!isdigit(p[1]) ||
|
||||
!isdigit(p[2]) ||
|
||||
@@ -958,7 +987,7 @@ static int fsck_commit(const struct object_id *oid,
|
||||
author_count = 0;
|
||||
while (buffer < buffer_end && skip_prefix(buffer, "author ", &buffer)) {
|
||||
author_count++;
|
||||
err = fsck_ident(&buffer, oid, OBJ_COMMIT, options);
|
||||
err = fsck_ident(&buffer, buffer_end, oid, OBJ_COMMIT, options);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@@ -970,7 +999,7 @@ static int fsck_commit(const struct object_id *oid,
|
||||
return err;
|
||||
if (buffer >= buffer_end || !skip_prefix(buffer, "committer ", &buffer))
|
||||
return report(options, oid, OBJ_COMMIT, FSCK_MSG_MISSING_COMMITTER, "invalid format - expected 'committer' line");
|
||||
err = fsck_ident(&buffer, oid, OBJ_COMMIT, options);
|
||||
err = fsck_ident(&buffer, buffer_end, oid, OBJ_COMMIT, options);
|
||||
if (err)
|
||||
return err;
|
||||
if (memchr(buffer_begin, '\0', size)) {
|
||||
@@ -1065,7 +1094,7 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
|
||||
goto done;
|
||||
}
|
||||
else
|
||||
ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
|
||||
ret = fsck_ident(&buffer, buffer_end, oid, OBJ_TAG, options);
|
||||
|
||||
if (buffer < buffer_end && (skip_prefix(buffer, "gpgsig ", &buffer) || skip_prefix(buffer, "gpgsig-sha256 ", &buffer))) {
|
||||
eol = memchr(buffer, '\n', buffer_end - buffer);
|
||||
|
||||
Reference in New Issue
Block a user