Skip to content

Commit 6932ec8

Browse files
pks-tgitster
authored andcommitted
diffcore-order: fix leaking buffer when parsing orderfiles
In `prepare_order()` we parse an orderfile and assign it to a global array. In order to save on some allocations, we replace newlines with NUL characters and then assign pointers into the allocated buffer to that array. This can cause the buffer to be completely unreferenced though in some cases, e.g. because the order file is empty or because we had to use `xmemdupz()` to copy the lines instead of NUL-terminating them. Refactor the code to always `xmemdupz()` the strings. This is a bit simpler, and it is rather unlikely that saving a handful of allocations really matters. This allows us to release the string buffer and thus plug the memory leak. Signed-off-by: Patrick Steinhardt <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cf8c423 commit 6932ec8

File tree

3 files changed

+9
-12
lines changed

3 files changed

+9
-12
lines changed

diffcore-order.c

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ static void prepare_order(const char *orderfile)
1414
{
1515
int cnt, pass;
1616
struct strbuf sb = STRBUF_INIT;
17-
void *map;
18-
char *cp, *endp;
17+
const char *cp, *endp;
1918
ssize_t sz;
2019

2120
if (order)
@@ -24,14 +23,13 @@ static void prepare_order(const char *orderfile)
2423
sz = strbuf_read_file(&sb, orderfile, 0);
2524
if (sz < 0)
2625
die_errno(_("failed to read orderfile '%s'"), orderfile);
27-
map = strbuf_detach(&sb, NULL);
28-
endp = (char *) map + sz;
26+
endp = sb.buf + sz;
2927

3028
for (pass = 0; pass < 2; pass++) {
3129
cnt = 0;
32-
cp = map;
30+
cp = sb.buf;
3331
while (cp < endp) {
34-
char *ep;
32+
const char *ep;
3533
for (ep = cp; ep < endp && *ep != '\n'; ep++)
3634
;
3735
/* cp to ep has one line */
@@ -40,12 +38,7 @@ static void prepare_order(const char *orderfile)
4038
else if (pass == 0)
4139
cnt++;
4240
else {
43-
if (*ep == '\n') {
44-
*ep = 0;
45-
order[cnt] = cp;
46-
} else {
47-
order[cnt] = xmemdupz(cp, ep - cp);
48-
}
41+
order[cnt] = xmemdupz(cp, ep - cp);
4942
cnt++;
5043
}
5144
if (ep < endp)
@@ -57,6 +50,8 @@ static void prepare_order(const char *orderfile)
5750
ALLOC_ARRAY(order, cnt);
5851
}
5952
}
53+
54+
strbuf_release(&sb);
6055
}
6156

6257
static int match_order(const char *path)

t/t4056-diff-order.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='diff order & rotate'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910

1011
create_files () {

t/t4204-patch-id.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ test_description='git patch-id'
55
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
66
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
77

8+
TEST_PASSES_SANITIZE_LEAK=true
89
. ./test-lib.sh
910

1011
test_expect_success 'setup' '

0 commit comments

Comments
 (0)