difftool: address a couple of resource/memory leaks

This change plugs a couple of memory leaks and makes sure that the file descriptor is closed in run_dir_diff(). Spotted by Coverity. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed May 4, 2017 at 15:55 UTC 5f3296c069bfe2872592f96b29bdcc8f0edd5eb8
1 file changed +23 -10
builtin/difftool.c
+23 -10
@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,
226 hashmap_entry_init(entry, strhash(buf.buf));
227 hashmap_add(result, entry);
228 }
229 + fclose(fp);
230 if (finish_command(&diff_files))
231 die("diff-files did not exit properly");
232 strbuf_release(&index_env);
@@ -439,8 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
440 }
441
442 if (lmode && status != 'C') {
442 - if (checkout_path(lmode, &loid, src_path, &lstate))
443 - return error("could not write '%s'", src_path);
443 + if (checkout_path(lmode, &loid, src_path, &lstate)) {
444 + ret = error("could not write '%s'", src_path);
445 + goto finish;
446 + }
447 }
448
449 if (rmode && !S_ISLNK(rmode)) {
@@ -456,9 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
459 hashmap_add(&working_tree_dups, entry);
460
461 if (!use_wt_file(workdir, dst_path, &roid)) {
459 - if (checkout_path(rmode, &roid, dst_path, &rstate))
460 - return error("could not write '%s'",
461 - dst_path);
462 + if (checkout_path(rmode, &roid, dst_path,
463 + &rstate)) {
464 + ret = error("could not write '%s'",
465 + dst_path);
466 + goto finish;
467 + }
468 } else if (!is_null_oid(&roid)) {
469 /*
470 * Changes in the working tree need special
@@ -473,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
479 ADD_CACHE_JUST_APPEND);
480
481 add_path(&rdir, rdir_len, dst_path);
476 - if (ensure_leading_directories(rdir.buf))
477 - return error("could not create "
478 - "directory for '%s'",
479 - dst_path);
482 + if (ensure_leading_directories(rdir.buf)) {
483 + ret = error("could not create "
484 + "directory for '%s'",
485 + dst_path);
486 + goto finish;
487 + }
488 add_path(&wtdir, wtdir_len, dst_path);
489 if (symlinks) {
490 if (symlink(wtdir.buf, rdir.buf)) {
@@ -497,13 +505,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
505 }
506 }
507
508 + fclose(fp);
509 + fp = NULL;
510 if (finish_command(&child)) {
511 ret = error("error occurred running diff --raw");
512 goto finish;
513 }
514
515 if (!i)
506 - return 0;
516 + goto finish;
517
518 /*
519 * Changes to submodules require special treatment.This loop writes a
@@ -626,6 +636,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,
636 exit_cleanup(tmpdir, rc);
637
638 finish:
639 + if (fp)
640 + fclose(fp);
641 +
642 free(lbase_dir);
643 free(rbase_dir);
644 strbuf_release(&ldir);