Skip to content

Commit 8532ed1

Browse files
committed
refdb_fs: convert reflog parsing to use parser
The refdb_fs code to parse the reflog currently uses a hand-rolled parser. Convert it to use our `git_parse_ctx` structure instead.
1 parent d8233fe commit 8532ed1

File tree

3 files changed

+42
-44
lines changed

3 files changed

+42
-44
lines changed

src/parse.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,16 @@ int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base)
101101
return 0;
102102
}
103103

104+
int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx)
105+
{
106+
if (ctx->line_len < GIT_OID_HEXSZ)
107+
return -1;
108+
if ((git_oid_fromstrn(out, ctx->line, GIT_OID_HEXSZ)) < 0)
109+
return -1;
110+
git_parse_advance_chars(ctx, GIT_OID_HEXSZ);
111+
return 0;
112+
}
113+
104114
int git_parse_peek(char *out, git_parse_ctx *ctx, int flags)
105115
{
106116
size_t remain = ctx->line_len;

src/parse.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ int git_parse_advance_expected(
5050
int git_parse_advance_ws(git_parse_ctx *ctx);
5151
int git_parse_advance_nl(git_parse_ctx *ctx);
5252
int git_parse_advance_digit(int64_t *out, git_parse_ctx *ctx, int base);
53+
int git_parse_advance_oid(git_oid *out, git_parse_ctx *ctx);
5354

5455
enum GIT_PARSE_PEEK_FLAGS {
5556
GIT_PARSE_PEEK_SKIP_WHITESPACE = (1 << 0)

src/refdb_fs.c

Lines changed: 31 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "futils.h"
1414
#include "filebuf.h"
1515
#include "pack.h"
16+
#include "parse.h"
1617
#include "reflog.h"
1718
#include "refdb.h"
1819
#include "iterator.h"
@@ -1651,67 +1652,53 @@ static int reflog_alloc(git_reflog **reflog, const char *name)
16511652

16521653
static int reflog_parse(git_reflog *log, const char *buf, size_t buf_size)
16531654
{
1654-
const char *ptr;
1655-
git_reflog_entry *entry;
1655+
git_parse_ctx parser = GIT_PARSE_CTX_INIT;
1656+
git_reflog_entry *entry = NULL;
16561657

1657-
#define seek_forward(_increase) do { \
1658-
if (_increase >= buf_size) { \
1659-
git_error_set(GIT_ERROR_INVALID, "ran out of data while parsing reflog"); \
1660-
goto fail; \
1661-
} \
1662-
buf += _increase; \
1663-
buf_size -= _increase; \
1664-
} while (0)
1665-
1666-
while (buf_size > GIT_REFLOG_SIZE_MIN) {
1667-
entry = git__calloc(1, sizeof(git_reflog_entry));
1668-
GIT_ERROR_CHECK_ALLOC(entry);
1658+
if ((git_parse_ctx_init(&parser, buf, buf_size)) < 0)
1659+
return -1;
16691660

1670-
entry->committer = git__calloc(1, sizeof(git_signature));
1671-
GIT_ERROR_CHECK_ALLOC(entry->committer);
1661+
for (; parser.remain_len; git_parse_advance_line(&parser)) {
1662+
const char *sig;
1663+
char c;
16721664

1673-
if (git_oid_fromstrn(&entry->oid_old, buf, GIT_OID_HEXSZ) < 0)
1674-
goto fail;
1675-
seek_forward(GIT_OID_HEXSZ + 1);
1665+
entry = git__calloc(1, sizeof(*entry));
1666+
GIT_ERROR_CHECK_ALLOC(entry);
16761667

1677-
if (git_oid_fromstrn(&entry->oid_cur, buf, GIT_OID_HEXSZ) < 0)
1678-
goto fail;
1679-
seek_forward(GIT_OID_HEXSZ + 1);
1668+
entry->committer = git__calloc(1, sizeof(*entry->committer));
1669+
GIT_ERROR_CHECK_ALLOC(entry->committer);
16801670

1681-
ptr = buf;
1671+
if (git_parse_advance_oid(&entry->oid_old, &parser) < 0 ||
1672+
git_parse_advance_expected(&parser, " ", 1) < 0 ||
1673+
git_parse_advance_oid(&entry->oid_cur, &parser) < 0)
1674+
goto error;
16821675

1683-
/* Seek forward to the end of the signature. */
1684-
while (*buf && *buf != '\t' && *buf != '\n')
1685-
seek_forward(1);
1676+
sig = parser.line;
1677+
while (git_parse_peek(&c, &parser, 0) == 0 && c != '\t' && c != '\n')
1678+
git_parse_advance_chars(&parser, 1);
16861679

1687-
if (git_signature__parse(entry->committer, &ptr, buf + 1, NULL, *buf) < 0)
1688-
goto fail;
1680+
if (git_signature__parse(entry->committer, &sig, parser.line, NULL, 0) < 0)
1681+
goto error;
16891682

1690-
if (*buf == '\t') {
1691-
/* We got a message. Read everything till we reach LF. */
1692-
seek_forward(1);
1693-
ptr = buf;
1683+
if (c == '\t') {
1684+
size_t len;
1685+
git_parse_advance_chars(&parser, 1);
16941686

1695-
while (*buf && *buf != '\n')
1696-
seek_forward(1);
1687+
len = parser.line_len;
1688+
if (parser.line[len - 1] == '\n')
1689+
len--;
16971690

1698-
entry->msg = git__strndup(ptr, buf - ptr);
1691+
entry->msg = git__strndup(parser.line, len);
16991692
GIT_ERROR_CHECK_ALLOC(entry->msg);
1700-
} else
1701-
entry->msg = NULL;
1702-
1703-
while (*buf && *buf == '\n' && buf_size > 1)
1704-
seek_forward(1);
1693+
}
17051694

17061695
if (git_vector_insert(&log->entries, entry) < 0)
1707-
goto fail;
1696+
goto error;
17081697
}
17091698

17101699
return 0;
17111700

1712-
#undef seek_forward
1713-
1714-
fail:
1701+
error:
17151702
git_reflog_entry__free(entry);
17161703

17171704
return -1;

0 commit comments

Comments
 (0)