summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2016-02-09 07:17:26 +0100
committerCarlos Martín Nieto <cmn@dwim.me>2016-02-09 07:17:26 +0100
commitf55eca167c2d08045dff929adb8ad8b81d8ccc86 (patch)
tree70dfd5c49bc2cbcc4fcdf74ab13ffc9f03bf2767
parent700f0aff24d9b292f24d802c3af3b5c1705193c5 (diff)
downloadlibgit2-cmn/header-field-2.tar.gz
commit: also match the first header field when searchingcmn/header-field-2
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.
-rw-r--r--src/commit.c39
-rw-r--r--tests/commit/parse.c4
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;
+ }
+
+ /* Skip until we find the field we're after */
+ if (git__prefixcmp(buf, field)) {
+ buf = eol + 1;
continue;
}
- h += strlen(field);
- eol = strchr(h, '\n');
- if (h[0] != ' ') {
- buf = h;
+ buf += strlen(field);
+ /* Check that we're not matching a prefix but the field itself */
+ if (buf[0] != ' ') {
+ buf = eol + 1;
continue;
}
- if (!eol)
- goto malformed;
- h++; /* skip the SP */
+ buf++; /* skip the SP */
- git_buf_put(out, h, eol - h);
+ 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);