From f55eca167c2d08045dff929adb8ad8b81d8ccc86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Tue, 9 Feb 2016 07:17:26 +0100 Subject: [PATCH] commit: also match the first header field when searching We were searching only past the first header field, which meant we were unable to find e.g. `tree` which is the first field. While here, make sure to set an error message in case we cannot find the field. --- src/commit.c | 39 ++++++++++++++++++++++----------------- tests/commit/parse.c | 4 ++++ 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/commit.c b/src/commit.c index 81aae489f..87301e0da 100644 --- a/src/commit.c +++ b/src/commit.c @@ -564,41 +564,45 @@ int git_commit_nth_gen_ancestor( int git_commit_header_field(git_buf *out, const git_commit *commit, const char *field) { - const char *buf = commit->raw_header; - const char *h, *eol; + const char *eol, *buf = commit->raw_header; git_buf_sanitize(out); - while ((h = strchr(buf, '\n')) && h[1] != '\0' && h[1] != '\n') { - h++; - if (git__prefixcmp(h, field)) { - buf = h; + + while ((eol = strchr(buf, '\n')) && eol[1] != '\0') { + /* We can skip continuations here */ + if (buf[0] == ' ') { + buf = eol + 1; continue; } - h += strlen(field); - eol = strchr(h, '\n'); - if (h[0] != ' ') { - buf = h; + /* Skip until we find the field we're after */ + if (git__prefixcmp(buf, field)) { + buf = eol + 1; continue; } - if (!eol) - goto malformed; - h++; /* skip the SP */ + buf += strlen(field); + /* Check that we're not matching a prefix but the field itself */ + if (buf[0] != ' ') { + buf = eol + 1; + continue; + } - git_buf_put(out, h, eol - h); + buf++; /* skip the SP */ + + git_buf_put(out, buf, eol - buf); if (git_buf_oom(out)) goto oom; /* If the next line starts with SP, it's multi-line, we must continue */ while (eol[1] == ' ') { git_buf_putc(out, '\n'); - h = eol + 2; - eol = strchr(h, '\n'); + buf = eol + 2; + eol = strchr(buf, '\n'); if (!eol) goto malformed; - git_buf_put(out, h, eol - h); + git_buf_put(out, buf, eol - buf); } if (git_buf_oom(out)) @@ -607,6 +611,7 @@ int git_commit_header_field(git_buf *out, const git_commit *commit, const char * return 0; } + giterr_set(GITERR_OBJECT, "no such field '%s'", field); return GIT_ENOTFOUND; malformed: diff --git a/tests/commit/parse.c b/tests/commit/parse.c index 388da078a..7c7264bc7 100644 --- a/tests/commit/parse.c +++ b/tests/commit/parse.c @@ -443,6 +443,10 @@ cpxtDQQMGYFpXK/71stq\n\ cl_git_pass(parse_commit(&commit, passing_commit_cases[4])); + cl_git_pass(git_commit_header_field(&buf, commit, "tree")); + cl_assert_equal_s("6b79e22d69bf46e289df0345a14ca059dfc9bdf6", buf.ptr); + git_buf_clear(&buf); + cl_git_pass(git_commit_header_field(&buf, commit, "parent")); cl_assert_equal_s("34734e478d6cf50c27c9d69026d93974d052c454", buf.ptr); git_buf_clear(&buf);