Skip to content

Commit 718f24a

Browse files
committed
commit: verify objects exist in git_commit_with_signature
There can be a significant difference between the system where we created the buffer (if at all) and when the caller provides us with the contents of a commit. Verify that the commit we are being asked to create references objects which do exist in the target repository.
1 parent 0974e02 commit 718f24a

File tree

1 file changed

+25
-2
lines changed

1 file changed

+25
-2
lines changed

src/commit.c

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -878,6 +878,14 @@ static void format_header_field(git_buf *out, const char *field, const char *con
878878
git_buf_putc(out, '\n');
879879
}
880880

881+
static const git_oid *commit_parent_from_commit(size_t n, void *payload)
882+
{
883+
const git_commit *commit = (const git_commit *) payload;
884+
885+
return git_array_get(commit->parent_ids, n);
886+
887+
}
888+
881889
int git_commit_create_with_signature(
882890
git_oid *out,
883891
git_repository *repo,
@@ -890,12 +898,26 @@ int git_commit_create_with_signature(
890898
const char *field;
891899
const char *header_end;
892900
git_buf commit = GIT_BUF_INIT;
901+
git_commit *parsed;
902+
git_array_oid_t parents = GIT_ARRAY_INIT;
893903

894-
/* We start by identifying the end of the commit header */
904+
/* The first step is to verify that all the tree and parents exist */
905+
parsed = git__calloc(1, sizeof(git_commit));
906+
GIT_ERROR_CHECK_ALLOC(parsed);
907+
if ((error = commit_parse(parsed, commit_content, strlen(commit_content), 0)) < 0)
908+
goto cleanup;
909+
910+
if ((error = validate_tree_and_parents(&parents, repo, &parsed->tree_id, commit_parent_from_commit, parsed, NULL, true)) < 0)
911+
goto cleanup;
912+
913+
git_array_clear(parents);
914+
915+
/* Then we start appending by identifying the end of the commit header */
895916
header_end = strstr(commit_content, "\n\n");
896917
if (!header_end) {
897918
git_error_set(GIT_ERROR_INVALID, "malformed commit contents");
898-
return -1;
919+
error = -1;
920+
goto cleanup;
899921
}
900922

901923
/* The header ends after the first LF */
@@ -919,6 +941,7 @@ int git_commit_create_with_signature(
919941
goto cleanup;
920942

921943
cleanup:
944+
git_commit__free(parsed);
922945
git_buf_dispose(&commit);
923946
return error;
924947
}

0 commit comments

Comments
 (0)