mirror of
https://github.com/git/git.git
synced 2024-10-28 04:49:43 +01:00
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 <ps@pks.im> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
cf8c4237eb
commit
6932ec8183
3 changed files with 9 additions and 12 deletions
|
@ -14,8 +14,7 @@ static void prepare_order(const char *orderfile)
|
||||||
{
|
{
|
||||||
int cnt, pass;
|
int cnt, pass;
|
||||||
struct strbuf sb = STRBUF_INIT;
|
struct strbuf sb = STRBUF_INIT;
|
||||||
void *map;
|
const char *cp, *endp;
|
||||||
char *cp, *endp;
|
|
||||||
ssize_t sz;
|
ssize_t sz;
|
||||||
|
|
||||||
if (order)
|
if (order)
|
||||||
|
@ -24,14 +23,13 @@ static void prepare_order(const char *orderfile)
|
||||||
sz = strbuf_read_file(&sb, orderfile, 0);
|
sz = strbuf_read_file(&sb, orderfile, 0);
|
||||||
if (sz < 0)
|
if (sz < 0)
|
||||||
die_errno(_("failed to read orderfile '%s'"), orderfile);
|
die_errno(_("failed to read orderfile '%s'"), orderfile);
|
||||||
map = strbuf_detach(&sb, NULL);
|
endp = sb.buf + sz;
|
||||||
endp = (char *) map + sz;
|
|
||||||
|
|
||||||
for (pass = 0; pass < 2; pass++) {
|
for (pass = 0; pass < 2; pass++) {
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
cp = map;
|
cp = sb.buf;
|
||||||
while (cp < endp) {
|
while (cp < endp) {
|
||||||
char *ep;
|
const char *ep;
|
||||||
for (ep = cp; ep < endp && *ep != '\n'; ep++)
|
for (ep = cp; ep < endp && *ep != '\n'; ep++)
|
||||||
;
|
;
|
||||||
/* cp to ep has one line */
|
/* cp to ep has one line */
|
||||||
|
@ -40,12 +38,7 @@ static void prepare_order(const char *orderfile)
|
||||||
else if (pass == 0)
|
else if (pass == 0)
|
||||||
cnt++;
|
cnt++;
|
||||||
else {
|
else {
|
||||||
if (*ep == '\n') {
|
order[cnt] = xmemdupz(cp, ep - cp);
|
||||||
*ep = 0;
|
|
||||||
order[cnt] = cp;
|
|
||||||
} else {
|
|
||||||
order[cnt] = xmemdupz(cp, ep - cp);
|
|
||||||
}
|
|
||||||
cnt++;
|
cnt++;
|
||||||
}
|
}
|
||||||
if (ep < endp)
|
if (ep < endp)
|
||||||
|
@ -57,6 +50,8 @@ static void prepare_order(const char *orderfile)
|
||||||
ALLOC_ARRAY(order, cnt);
|
ALLOC_ARRAY(order, cnt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
strbuf_release(&sb);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match_order(const char *path)
|
static int match_order(const char *path)
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='diff order & rotate'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
create_files () {
|
create_files () {
|
||||||
|
|
|
@ -5,6 +5,7 @@ test_description='git patch-id'
|
||||||
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main
|
||||||
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME
|
||||||
|
|
||||||
|
TEST_PASSES_SANITIZE_LEAK=true
|
||||||
. ./test-lib.sh
|
. ./test-lib.sh
|
||||||
|
|
||||||
test_expect_success 'setup' '
|
test_expect_success 'setup' '
|
||||||
|
|
Loading…
Reference in a new issue