Skip to content

Commit d4fe402

Browse files
committed
merge: check return value of git_commit_list_insert
The function `git_commit_list_insert` dynamically allocates memory and may thus fail to insert a given commit, but we didn't check for that in several places in "merge.c". Convert surrounding functions to return error codes and check whether `git_commit_list_insert` was successful, returning an error if not.
1 parent c048618 commit d4fe402

File tree

1 file changed

+25
-16
lines changed

1 file changed

+25
-16
lines changed

src/merge.c

Lines changed: 25 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -310,46 +310,55 @@ static int interesting(git_pqueue *list)
310310
return 0;
311311
}
312312

313-
static void clear_commit_marks_1(git_commit_list **plist,
313+
static int clear_commit_marks_1(git_commit_list **plist,
314314
git_commit_list_node *commit, unsigned int mark)
315315
{
316316
while (commit) {
317317
unsigned int i;
318318

319319
if (!(mark & commit->flags))
320-
return;
320+
return 0;
321321

322322
commit->flags &= ~mark;
323323

324324
for (i = 1; i < commit->out_degree; i++) {
325325
git_commit_list_node *p = commit->parents[i];
326-
git_commit_list_insert(p, plist);
326+
if (git_commit_list_insert(p, plist) == NULL)
327+
return -1;
327328
}
328329

329330
commit = commit->out_degree ? commit->parents[0] : NULL;
330331
}
332+
333+
return 0;
331334
}
332335

333-
static void clear_commit_marks_many(git_vector *commits, unsigned int mark)
336+
static int clear_commit_marks_many(git_vector *commits, unsigned int mark)
334337
{
335338
git_commit_list *list = NULL;
336339
git_commit_list_node *c;
337340
unsigned int i;
338341

339342
git_vector_foreach(commits, i, c) {
340-
git_commit_list_insert(c, &list);
343+
if (git_commit_list_insert(c, &list) == NULL)
344+
return -1;
341345
}
342346

343347
while (list)
344-
clear_commit_marks_1(&list, git_commit_list_pop(&list), mark);
348+
if (clear_commit_marks_1(&list, git_commit_list_pop(&list), mark) < 0)
349+
return -1;
350+
return 0;
345351
}
346352

347-
static void clear_commit_marks(git_commit_list_node *commit, unsigned int mark)
353+
static int clear_commit_marks(git_commit_list_node *commit, unsigned int mark)
348354
{
349355
git_commit_list *list = NULL;
350-
git_commit_list_insert(commit, &list);
356+
if (git_commit_list_insert(commit, &list) == NULL)
357+
return -1;
351358
while (list)
352-
clear_commit_marks_1(&list, git_commit_list_pop(&list), mark);
359+
if (clear_commit_marks_1(&list, git_commit_list_pop(&list), mark) < 0)
360+
return -1;
361+
return 0;
353362
}
354363

355364
static int paint_down_to_common(
@@ -466,10 +475,11 @@ static int remove_redundant(git_revwalk *walk, git_vector *commits)
466475
redundant[filled_index[j]] = 1;
467476
}
468477

469-
clear_commit_marks(commit, ALL_FLAGS);
470-
clear_commit_marks_many(&work, ALL_FLAGS);
471-
472478
git_commit_list_free(&common);
479+
480+
if ((error = clear_commit_marks(commit, ALL_FLAGS)) < 0 ||
481+
(error = clear_commit_marks_many(&work, ALL_FLAGS)) < 0)
482+
goto done;
473483
}
474484

475485
for (i = 0; i < commits->length; ++i) {
@@ -531,10 +541,9 @@ int git_merge__bases_many(git_commit_list **out, git_revwalk *walk, git_commit_l
531541
while (result)
532542
git_vector_insert(&redundant, git_commit_list_pop(&result));
533543

534-
clear_commit_marks(one, ALL_FLAGS);
535-
clear_commit_marks_many(twos, ALL_FLAGS);
536-
537-
if ((error = remove_redundant(walk, &redundant)) < 0) {
544+
if ((error = clear_commit_marks(one, ALL_FLAGS)) < 0 ||
545+
(error = clear_commit_marks_many(twos, ALL_FLAGS)) < 0 ||
546+
(error = remove_redundant(walk, &redundant)) < 0) {
538547
git_vector_free(&redundant);
539548
return error;
540549
}

0 commit comments

Comments
 (0)