|
13 | 13 | #include "futils.h" |
14 | 14 | #include "filebuf.h" |
15 | 15 | #include "pack.h" |
| 16 | +#include "parse.h" |
16 | 17 | #include "reflog.h" |
17 | 18 | #include "refdb.h" |
18 | 19 | #include "iterator.h" |
@@ -1651,67 +1652,53 @@ static int reflog_alloc(git_reflog **reflog, const char *name) |
1651 | 1652 |
|
1652 | 1653 | static int reflog_parse(git_reflog *log, const char *buf, size_t buf_size) |
1653 | 1654 | { |
1654 | | - const char *ptr; |
1655 | | - git_reflog_entry *entry; |
| 1655 | + git_parse_ctx parser = GIT_PARSE_CTX_INIT; |
| 1656 | + git_reflog_entry *entry = NULL; |
1656 | 1657 |
|
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; |
1669 | 1660 |
|
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; |
1672 | 1664 |
|
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); |
1676 | 1667 |
|
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); |
1680 | 1670 |
|
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; |
1682 | 1675 |
|
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); |
1686 | 1679 |
|
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; |
1689 | 1682 |
|
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); |
1694 | 1686 |
|
1695 | | - while (*buf && *buf != '\n') |
1696 | | - seek_forward(1); |
| 1687 | + len = parser.line_len; |
| 1688 | + if (parser.line[len - 1] == '\n') |
| 1689 | + len--; |
1697 | 1690 |
|
1698 | | - entry->msg = git__strndup(ptr, buf - ptr); |
| 1691 | + entry->msg = git__strndup(parser.line, len); |
1699 | 1692 | 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 | + } |
1705 | 1694 |
|
1706 | 1695 | if (git_vector_insert(&log->entries, entry) < 0) |
1707 | | - goto fail; |
| 1696 | + goto error; |
1708 | 1697 | } |
1709 | 1698 |
|
1710 | 1699 | return 0; |
1711 | 1700 |
|
1712 | | -#undef seek_forward |
1713 | | - |
1714 | | -fail: |
| 1701 | +error: |
1715 | 1702 | git_reflog_entry__free(entry); |
1716 | 1703 |
|
1717 | 1704 | return -1; |
|
0 commit comments