diff options
author | Junio C Hamano <gitster@pobox.com> | 2022-09-13 12:21:07 -0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2022-09-13 12:21:07 -0700 |
commit | 72869e750bf62fa313e7854d18e48c083f4720cc (patch) | |
tree | 3b92e3660e7714d3b603bd01b617c712ecb93e15 | |
parent | ac8035a2affdf30f2c691ad760826d955bba0507 (diff) | |
parent | 1490d7d82d5bd504b095c4db030a98b8080c596a (diff) | |
download | git-72869e750bf62fa313e7854d18e48c083f4720cc.tar.gz |
Merge branch 'jk/is-promisor-object-keep-tree-in-use' into maint
An earlier optimization discarded a tree-object buffer that is
still in use, which has been corrected.
* jk/is-promisor-object-keep-tree-in-use:
is_promisor_object(): fix use-after-free of tree buffer
-rw-r--r-- | packfile.c | 15 | ||||
-rwxr-xr-x | t/t5616-partial-clone.sh | 7 |
2 files changed, 20 insertions, 2 deletions
diff --git a/packfile.c b/packfile.c index e5b1d0ed76..75c254e0e0 100644 --- a/packfile.c +++ b/packfile.c @@ -2229,7 +2229,17 @@ static int add_promisor_object(const struct object_id *oid, void *set_) { struct oidset *set = set_; - struct object *obj = parse_object(the_repository, oid); + struct object *obj; + int we_parsed_object; + + obj = lookup_object(the_repository, oid); + if (obj && obj->parsed) { + we_parsed_object = 0; + } else { + we_parsed_object = 1; + obj = parse_object(the_repository, oid); + } + if (!obj) return 1; @@ -2251,7 +2261,8 @@ static int add_promisor_object(const struct object_id *oid, return 0; while (tree_entry_gently(&desc, &entry)) oidset_insert(set, &entry.oid); - free_tree_buffer(tree); + if (we_parsed_object) + free_tree_buffer(tree); } else if (obj->type == OBJ_COMMIT) { struct commit *commit = (struct commit *) obj; struct commit_list *parents = commit->parents; diff --git a/t/t5616-partial-clone.sh b/t/t5616-partial-clone.sh index 4a3778d04a..9aeacc2f6a 100755 --- a/t/t5616-partial-clone.sh +++ b/t/t5616-partial-clone.sh @@ -49,6 +49,13 @@ test_expect_success 'do partial clone 1' ' test "$(git -C pc1 config --local remote.origin.partialclonefilter)" = "blob:none" ' +test_expect_success 'rev-list --missing=allow-promisor on partial clone' ' + git -C pc1 rev-list --objects --missing=allow-promisor HEAD >actual && + git -C pc1 rev-list --objects --missing=print HEAD >expect.raw && + grep -v "^?" expect.raw >expect && + test_cmp expect actual +' + test_expect_success 'verify that .promisor file contains refs fetched' ' ls pc1/.git/objects/pack/pack-*.promisor >promisorlist && test_line_count = 1 promisorlist && |