Skip to content

Commit 4f33a63

Browse files
avarderrickstolee
authored andcommitted
list-objects: handle NULL function pointers
If a caller to traverse_commit_list() specifies the options for the --objects flag but does not specify a show_object function pointer, the result is a segfault. This is currently visible by running 'git bundle create --objects HEAD'. We could fix this problem by supplying a no-op callback in builtin/bundle.c, but that only solves the problem for one builtin, leaving this segfault open for other callers. Replace all callers of the show_commit and show_object function pointers in list-objects.c to call helper functions show_commit() and show_object() which check that the given context has non-NULL functions before passing the necessary data. One extra benefit is that it reduces duplication due to passing ctx->show_data to every caller. Test that this segfault no longer occurs for 'git bundle'. Co-authored-by: Derrick Stolee <[email protected]> Signed-off-by: Ævar Arnfjörð Bjarmason <[email protected]> Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent f0d2f84 commit 4f33a63

File tree

3 files changed

+36
-5
lines changed

3 files changed

+36
-5
lines changed

bundle.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -544,6 +544,8 @@ int create_bundle(struct repository *r, const char *path,
544544
die("revision walk setup failed");
545545
bpi.fd = bundle_fd;
546546
bpi.pending = &revs_copy.pending;
547+
548+
revs.blob_objects = revs.tree_objects = 0;
547549
traverse_commit_list(&revs, write_bundle_prerequisites, NULL, &bpi);
548550
object_array_remove_duplicates(&revs_copy.pending);
549551

list-objects.c

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,23 @@ struct traversal_context {
2121
struct filter *filter;
2222
};
2323

24+
static void show_commit(struct traversal_context *ctx,
25+
struct commit *commit)
26+
{
27+
if (!ctx->show_commit)
28+
return;
29+
ctx->show_commit(commit, ctx->show_data);
30+
}
31+
32+
static void show_object(struct traversal_context *ctx,
33+
struct object *object,
34+
const char *name)
35+
{
36+
if (!ctx->show_object)
37+
return;
38+
ctx->show_object(object, name, ctx->show_data);
39+
}
40+
2441
static void process_blob(struct traversal_context *ctx,
2542
struct blob *blob,
2643
struct strbuf *path,
@@ -60,7 +77,7 @@ static void process_blob(struct traversal_context *ctx,
6077
if (r & LOFR_MARK_SEEN)
6178
obj->flags |= SEEN;
6279
if (r & LOFR_DO_SHOW)
63-
ctx->show_object(obj, path->buf, ctx->show_data);
80+
show_object(ctx, obj, path->buf);
6481
strbuf_setlen(path, pathlen);
6582
}
6683

@@ -194,7 +211,7 @@ static void process_tree(struct traversal_context *ctx,
194211
if (r & LOFR_MARK_SEEN)
195212
obj->flags |= SEEN;
196213
if (r & LOFR_DO_SHOW)
197-
ctx->show_object(obj, base->buf, ctx->show_data);
214+
show_object(ctx, obj, base->buf);
198215
if (base->len)
199216
strbuf_addch(base, '/');
200217

@@ -210,7 +227,7 @@ static void process_tree(struct traversal_context *ctx,
210227
if (r & LOFR_MARK_SEEN)
211228
obj->flags |= SEEN;
212229
if (r & LOFR_DO_SHOW)
213-
ctx->show_object(obj, base->buf, ctx->show_data);
230+
show_object(ctx, obj, base->buf);
214231

215232
strbuf_setlen(base, baselen);
216233
free_tree_buffer(tree);
@@ -228,7 +245,7 @@ static void process_tag(struct traversal_context *ctx,
228245
if (r & LOFR_MARK_SEEN)
229246
tag->object.flags |= SEEN;
230247
if (r & LOFR_DO_SHOW)
231-
ctx->show_object(&tag->object, name, ctx->show_data);
248+
show_object(ctx, &tag->object, name);
232249
}
233250

234251
static void mark_edge_parents_uninteresting(struct commit *commit,
@@ -402,7 +419,7 @@ static void do_traverse(struct traversal_context *ctx)
402419
if (r & LOFR_MARK_SEEN)
403420
commit->object.flags |= SEEN;
404421
if (r & LOFR_DO_SHOW)
405-
ctx->show_commit(commit, ctx->show_data);
422+
show_commit(ctx, commit);
406423

407424
if (ctx->revs->tree_blobs_in_commit_order)
408425
/*

t/t6020-bundle-misc.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,4 +475,16 @@ test_expect_success 'clone from bundle' '
475475
test_cmp expect actual
476476
'
477477

478+
test_expect_success 'unfiltered bundle with --objects' '
479+
git bundle create all-objects.bdl \
480+
--all --objects &&
481+
git bundle create all.bdl \
482+
--all &&
483+
484+
# Compare the headers of these files.
485+
sed -n -e "/^$/q" -e "p" all.bdl >expect &&
486+
sed -n -e "/^$/q" -e "p" all-objects.bdl >actual &&
487+
test_cmp expect actual
488+
'
489+
478490
test_done

0 commit comments

Comments
 (0)