Skip to content

Commit a14d49c

Browse files
peffgitster
authored andcommitted
sparse-checkout: refactor temporary sparse_checkout_patterns
In update_working_directory(), we take in a pattern_list, attach it to the repository index by assigning it to index->sparse_checkout_patterns, and then call unpack_trees. Afterwards, we remove it by setting index->sparse_checkout_patterns back to NULL. But there are two possible leaks here: 1. If the index already had a populated sparse_checkout_patterns, we've obliterated it. We can fix this by saving and restoring it, rather than always setting it back to NULL. 2. We may call the function with a NULL pattern_list, expecting it to use the on-disk sparse file. In that case, the index routines will lazy-load the sparse patterns automatically. But now at the end of the function when we restore the patterns, we'll leak those lazy-loaded ones! We can fix this by freeing the pattern list before overwriting its pointer whenever it does not match what was passed in (in practice this should only happen when the passed-in list is NULL, but this is erring on the defensive side). Together these remove 48 indirect leaks found in t1091. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d765fa0 commit a14d49c

File tree

1 file changed

+8
-1
lines changed

1 file changed

+8
-1
lines changed

builtin/sparse-checkout.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,11 +205,13 @@ static int update_working_directory(struct pattern_list *pl)
205205
struct unpack_trees_options o;
206206
struct lock_file lock_file = LOCK_INIT;
207207
struct repository *r = the_repository;
208+
struct pattern_list *old_pl;
208209

209210
/* If no branch has been checked out, there are no updates to make. */
210211
if (is_index_unborn(r->index))
211212
return UPDATE_SPARSITY_SUCCESS;
212213

214+
old_pl = r->index->sparse_checkout_patterns;
213215
r->index->sparse_checkout_patterns = pl;
214216

215217
memset(&o, 0, sizeof(o));
@@ -241,7 +243,12 @@ static int update_working_directory(struct pattern_list *pl)
241243

242244
clean_tracked_sparse_directories(r);
243245

244-
r->index->sparse_checkout_patterns = NULL;
246+
if (r->index->sparse_checkout_patterns != pl) {
247+
clear_pattern_list(r->index->sparse_checkout_patterns);
248+
FREE_AND_NULL(r->index->sparse_checkout_patterns);
249+
}
250+
r->index->sparse_checkout_patterns = old_pl;
251+
245252
return result;
246253
}
247254

0 commit comments

Comments
 (0)