Skip to content

Commit 0cc702d

Browse files
ttaylorrgitster
authored andcommitted
pack-bitmap: prevent pattern leak on pseudo-merge re-assignment
When "bitmapPseudoMerge.*.pattern" appears more than once for the same group, `pseudo_merge_config()` frees the old `regex_t *` pointer but does not call `regfree()` on it first. This leaks whatever internal state `regcomp()` allocated. The final cleanup path in `pseudo_merge_group_release()` does call `regfree()` before `free()`, so only the intermediate replacement is affected. Fix this by guarding the replacement with a NULL check and calling `regfree()` before `free()` when the pointer is non-NULL. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 2ad7d58 commit 0cc702d

2 files changed

Lines changed: 34 additions & 1 deletion

File tree

pseudo-merge.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,10 @@ static int pseudo_merge_config(const char *var, const char *value,
150150
if (!strcmp(key, "pattern")) {
151151
struct strbuf re = STRBUF_INIT;
152152

153-
free(group->pattern);
153+
if (group->pattern) {
154+
regfree(group->pattern);
155+
free(group->pattern);
156+
}
154157
if (*value != '^')
155158
strbuf_addch(&re, '^');
156159
strbuf_addstr(&re, value);

t/t5333-pseudo-merge-bitmaps.sh

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -662,4 +662,34 @@ test_expect_success 'sampleRate=0 does not cause division by zero' '
662662
)
663663
'
664664

665+
test_expect_success 'duplicate pseudo-merge pattern does not leak' '
666+
git init pseudo-merge-dup-pattern &&
667+
test_when_finished "rm -fr pseudo-merge-dup-pattern" &&
668+
669+
(
670+
cd pseudo-merge-dup-pattern &&
671+
672+
test_commit_bulk 64 &&
673+
tag_everything &&
674+
git repack -ad &&
675+
676+
pack=$(ls .git/objects/pack/pack-*.pack) &&
677+
678+
# Set the same group'\''s pattern twice. The second
679+
# assignment should cleanly release the compiled regex
680+
# from the first without leaking.
681+
git config bitmapPseudoMerge.test.pattern "refs/tags/" &&
682+
git config --add bitmapPseudoMerge.test.pattern "refs/tags/" &&
683+
git config bitmapPseudoMerge.test.maxMerges 1 &&
684+
git config bitmapPseudoMerge.test.threshold now &&
685+
git config bitmapPseudoMerge.test.stableThreshold never &&
686+
687+
git rev-parse HEAD~63 |
688+
test-tool bitmap write "$(basename $pack)" &&
689+
690+
test_pseudo_merges >merges &&
691+
test_line_count = 1 merges
692+
)
693+
'
694+
665695
test_done

0 commit comments

Comments
 (0)