submodule: fix leaking fetch tasks

When done with a fetch task used for parallel fetches of submodules, we need to both call `fetch_task_release()` to release the task's contents and `free()` to release the task itself. Most sites do this already, but some only call `fetch_task_release()` and thus leak memory. While we could trivially fix this by adding the two missing calls to free(3P), the result would be that we always call both functions. Let's thus refactor the code such that `fetch_task_release()` also frees the structure itself. Rename it to `fetch_task_free()` accordingly. Signed-off-by: Patrick Steinhardt <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Patrick Steinhardt committed Aug 8, 2024 at 09:35 UTC 1a7e5efdb06a7e3087bf9068220b011f006db43f
1 file changed +7 -10
submodule.c
+7 -10
@@ -1496,7 +1496,7 @@ static const struct submodule *get_non_gitmodules_submodule(const char *path)
1496 return (const struct submodule *) ret;
1497 }
1498
1499 -static void fetch_task_release(struct fetch_task *p)
1499 +static void fetch_task_free(struct fetch_task *p)
1500 {
1501 if (p->free_sub)
1502 free((void*)p->sub);
@@ -1508,6 +1508,7 @@ static void fetch_task_release(struct fetch_task *p)
1508 FREE_AND_NULL(p->repo);
1509
1510 strvec_clear(&p->git_args);
1511 + free(p);
1512 }
1513
1514 static struct repository *get_submodule_repo_for(struct repository *r,
@@ -1576,8 +1577,7 @@ static struct fetch_task *fetch_task_create(struct submodule_parallel_fetch *spf
1577 return task;
1578
1579 cleanup:
1579 - fetch_task_release(task);
1580 - free(task);
1580 + fetch_task_free(task);
1581 return NULL;
1582 }
1583
@@ -1607,8 +1607,7 @@ get_fetch_task_from_index(struct submodule_parallel_fetch *spf,
1607 } else {
1608 struct strbuf empty_submodule_path = STRBUF_INIT;
1609
1610 - fetch_task_release(task);
1611 - free(task);
1610 + fetch_task_free(task);
1611
1612 /*
1613 * An empty directory is normal,
@@ -1654,8 +1653,7 @@ get_fetch_task_from_changed(struct submodule_parallel_fetch *spf,
1653 cs_data->path,
1654 repo_find_unique_abbrev(the_repository, cs_data->super_oid, DEFAULT_ABBREV));
1655
1657 - fetch_task_release(task);
1658 - free(task);
1656 + fetch_task_free(task);
1657 continue;
1658 }
1659
@@ -1763,7 +1761,7 @@ static int fetch_start_failure(struct strbuf *err UNUSED,
1761
1762 spf->result = 1;
1763
1766 - fetch_task_release(task);
1764 + fetch_task_free(task);
1765 return 0;
1766 }
1767
@@ -1828,8 +1826,7 @@ static int fetch_finish(int retvalue, struct strbuf *err UNUSED,
1826 }
1827
1828 out:
1831 - fetch_task_release(task);
1832 -
1829 + fetch_task_free(task);
1830 return 0;
1831 }
1832