Skip to content

Commit 4318d3a

Browse files
peffgitster
authored andcommitted
dir.c: free strings in sparse cone pattern hashmaps
The pattern_list structs used for cone-mode sparse lookups use a few extra hashmaps. These store pattern_entry structs, each of which has its own heap-allocated pattern string. When we clean up the hashmaps, we free the individual pattern_entry structs, but forget to clean up the embedded strings, causing memory leaks. We can fix this by iterating over the hashmaps to free the extra strings. This reduces the numbers of leaks in t7002 from 22 to 9. One alternative here would be to make the string a FLEX_ARRAY member of the pattern_entry. Then there's no extra free() required, and as a bonus it would be a little more efficient. However, some of the refactoring gets awkward, as we are often assigning strings allocated by helper functions. So let's just fix the leak for now, and we can explore bigger refactoring separately. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 4d7f95e commit 4318d3a

File tree

1 file changed

+15
-4
lines changed

1 file changed

+15
-4
lines changed

dir.c

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -726,6 +726,17 @@ static char *dup_and_filter_pattern(const char *pattern)
726726
return result;
727727
}
728728

729+
static void clear_pattern_entry_hashmap(struct hashmap *map)
730+
{
731+
struct hashmap_iter iter;
732+
struct pattern_entry *entry;
733+
734+
hashmap_for_each_entry(map, &iter, entry, ent) {
735+
free(entry->pattern);
736+
}
737+
hashmap_clear_and_free(map, struct pattern_entry, ent);
738+
}
739+
729740
static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern *given)
730741
{
731742
struct pattern_entry *translated;
@@ -855,8 +866,8 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern
855866

856867
clear_hashmaps:
857868
warning(_("disabling cone pattern matching"));
858-
hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent);
859-
hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent);
869+
clear_pattern_entry_hashmap(&pl->recursive_hashmap);
870+
clear_pattern_entry_hashmap(&pl->parent_hashmap);
860871
pl->use_cone_patterns = 0;
861872
}
862873

@@ -956,8 +967,8 @@ void clear_pattern_list(struct pattern_list *pl)
956967
free(pl->patterns[i]);
957968
free(pl->patterns);
958969
free(pl->filebuf);
959-
hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent);
960-
hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent);
970+
clear_pattern_entry_hashmap(&pl->recursive_hashmap);
971+
clear_pattern_entry_hashmap(&pl->parent_hashmap);
961972

962973
memset(pl, 0, sizeof(*pl));
963974
}

0 commit comments

Comments
 (0)