Skip to content

Commit 9df0fc3

Browse files
phillipwoodgitster
authored andcommitted
xdiff: fix a memory leak
Although the patience and histogram algorithms initialize the environment they do not free it if there is an error. In contrast for the Myers algorithm the environment is initalized in xdl_do_diff() and it is freed if there is an error. Fix this by always initializing the environment in xdl_do_diff() and freeing it there if there is an error. Remove the comment in do_patience_diff() about the environment being freed by xdl_diff() as it is not accurate because (a) xdl_diff() does not do that if there is an error and (b) xdl_diff() is not the only caller. Reported-by: Junio C Hamano <[email protected]> Signed-off-by: Phillip Wood <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 2b9c120 commit 9df0fc3

File tree

3 files changed

+17
-23
lines changed

3 files changed

+17
-23
lines changed

xdiff/xdiffi.c

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -315,16 +315,19 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
315315
long *kvd, *kvdf, *kvdb;
316316
xdalgoenv_t xenv;
317317
diffdata_t dd1, dd2;
318+
int res;
318319

319-
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF)
320-
return xdl_do_patience_diff(mf1, mf2, xpp, xe);
321-
322-
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF)
323-
return xdl_do_histogram_diff(mf1, mf2, xpp, xe);
320+
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0)
321+
return -1;
324322

325-
if (xdl_prepare_env(mf1, mf2, xpp, xe) < 0) {
323+
if (XDF_DIFF_ALG(xpp->flags) == XDF_PATIENCE_DIFF) {
324+
res = xdl_do_patience_diff(mf1, mf2, xpp, xe);
325+
goto out;
326+
}
326327

327-
return -1;
328+
if (XDF_DIFF_ALG(xpp->flags) == XDF_HISTOGRAM_DIFF) {
329+
res = xdl_do_histogram_diff(mf1, mf2, xpp, xe);
330+
goto out;
328331
}
329332

330333
/*
@@ -359,17 +362,15 @@ int xdl_do_diff(mmfile_t *mf1, mmfile_t *mf2, xpparam_t const *xpp,
359362
dd2.rchg = xe->xdf2.rchg;
360363
dd2.rindex = xe->xdf2.rindex;
361364

362-
if (xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
363-
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0, &xenv) < 0) {
364-
365-
xdl_free(kvd);
366-
xdl_free_env(xe);
367-
return -1;
368-
}
369-
365+
res = xdl_recs_cmp(&dd1, 0, dd1.nrec, &dd2, 0, dd2.nrec,
366+
kvdf, kvdb, (xpp->flags & XDF_NEED_MINIMAL) != 0,
367+
&xenv);
370368
xdl_free(kvd);
369+
out:
370+
if (res < 0)
371+
xdl_free_env(xe);
371372

372-
return 0;
373+
return res;
373374
}
374375

375376

xdiff/xhistogram.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -372,9 +372,6 @@ static int histogram_diff(xpparam_t const *xpp, xdfenv_t *env,
372372
int xdl_do_histogram_diff(mmfile_t *file1, mmfile_t *file2,
373373
xpparam_t const *xpp, xdfenv_t *env)
374374
{
375-
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
376-
return -1;
377-
378375
return histogram_diff(xpp, env,
379376
env->xdf1.dstart + 1, env->xdf1.dend - env->xdf1.dstart + 1,
380377
env->xdf2.dstart + 1, env->xdf2.dend - env->xdf2.dstart + 1);

xdiff/xpatience.c

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -373,10 +373,6 @@ static int patience_diff(mmfile_t *file1, mmfile_t *file2,
373373
int xdl_do_patience_diff(mmfile_t *file1, mmfile_t *file2,
374374
xpparam_t const *xpp, xdfenv_t *env)
375375
{
376-
if (xdl_prepare_env(file1, file2, xpp, env) < 0)
377-
return -1;
378-
379-
/* environment is cleaned up in xdl_diff() */
380376
return patience_diff(file1, file2, xpp, env,
381377
1, env->xdf1.nrec, 1, env->xdf2.nrec);
382378
}

0 commit comments

Comments
 (0)