{"thread":{"id":"45809","subject":"[PATCH 00/26] Address a couple of issues identified by Coverity","startedAt":"2017-04-26T20:19:25Z","lastAt":"2017-05-11T11:33:47Z","messageCount":178,"participants":["Johannes Schindelin","Stefan Beller","Junio C Hamano","Johannes Sixt","Jeff King","Lars Schneider","René Scharfe"],"isPatch":true,"patchVersion":1,"patchTotal":26},"messages":[{"id":"317969","messageId":"cover.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":null,"subject":"[PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:13Z","receivedAt":"2017-04-26T20:19:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"I recently registered the git-for-windows fork with Coverity to ensure\nthat even the Windows-specific patches get some static analysis love.\n\nWhile at it, I squashed a couple of obvious issues in the part that is\nnot Windows-specific.\n\nNote: while this patch series squashes some of those issues, the\nremaining issues are not necessarily all false positives (e.g. Coverity\ngetting fooled by our FLEX_ARRAY trick into believing that the last\nmember of the struct is indeed a 0 or 1 size array) or intentional (e.g.\nbuiltins not releasing memory because exit() is called right after\nreturning from the function that leaks memory).\n\nNotable examples of the remaining issues are:\n\n- a couple of callers of shorten_unambiguous_ref() assume that they do\n  not have to release the memory returned from that function, often\n  assigning the pointer to a `const` variable that typically does not\n  hold a pointer that needs to be free()d. My hunch is that we will want\n  to convert that function to have a fixed number of static buffers and\n  use those in a round robin fashion à la sha1_to_hex().\n\n- pack-redundant.c seems to have hard-to-reason-about code paths that\n  may eventually leak memory. Essentially, the custody of the allocated\n  memory is not clear at all.\n\n- fast-import.c calls strbuf_detach() on the command_buf without any\n  obvious rationale. Turns out that *some* code paths assign\n  command_buf.buf to a `recent_command` which releases the buffer later.\n  However, from a cursory look it appears to me as if there are some\n  other code paths that skip that assignment, effectively causing a memory\n  leak once strbuf_detach() is called.\n\nSadly, I lack the time to pursue those remaining issues further.\n\n\nJohannes Schindelin (26):\n  mingw: avoid memory leak when splitting PATH\n  winansi: avoid use of uninitialized value\n  winansi: avoid buffer overrun\n  add_commit_patch_id(): avoid allocating memory unnecessarily\n  git_config_rename_section_in_file(): avoid resource leak\n  get_mail_commit_oid(): avoid resource leak\n  http-backend: avoid memory leaks\n  difftool: close file descriptors after reading\n  status: close file descriptor after reading git-rebase-todo\n  Check for EOF while parsing mails\n  cat-file: fix memory leak\n  checkout: fix memory leak\n  split_commit_in_progress(): fix memory leak\n  setup_bare_git_dir(): fix memory leak\n  setup_discovered_git_dir(): fix memory leak\n  pack-redundant: plug memory leak\n  mktree: plug memory leaks reported by Coverity\n  fast-export: avoid leaking memory in handle_tag()\n  receive-pack: plug memory leak in update()\n  line-log: avoid memory leak\n  shallow: avoid memory leak\n  add_reflog_for_walk: avoid memory leak\n  remote: plug memory leak in match_explicit()\n  name-rev: avoid leaking memory in the `deref` case\n  show_worktree(): plug memory leak\n  submodule_uses_worktrees(): plug memory leak\n\n builtin/am.c             | 11 ++++++-----\n builtin/cat-file.c       |  1 +\n builtin/checkout.c       |  1 +\n builtin/difftool.c       |  2 ++\n builtin/fast-export.c    |  1 +\n builtin/mailsplit.c      |  2 +-\n builtin/mktree.c         |  5 +++--\n builtin/name-rev.c       |  7 +++++--\n builtin/pack-redundant.c |  1 +\n builtin/receive-pack.c   |  4 +++-\n builtin/worktree.c       |  8 +++++---\n compat/mingw.c           |  4 +++-\n compat/winansi.c         |  7 +++++++\n config.c                 |  5 ++++-\n http-backend.c           |  6 +++++-\n line-log.c               |  1 +\n mailinfo.c               |  2 +-\n patch-ids.c              |  3 ++-\n reflog-walk.c            |  6 +++++-\n remote.c                 |  5 +++--\n setup.c                  | 11 ++++++++---\n shallow.c                |  8 ++++++--\n worktree.c               |  2 +-\n wt-status.c              |  8 +++++++-\n 24 files changed, 82 insertions(+), 29 deletions(-)\n\n\nbase-commit: e2cb6ab84c94f147f1259260961513b40c36108a\nPublished-As: https://github.com/dscho/git/releases/tag/coverity-v1\nFetch-It-Via: git fetch https://github.com/dscho/git coverity-v1\n\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"317970","messageId":"da7b1af7d820c3f573d449e46407e2774ebc04db.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 01/26] mingw: avoid memory leak when splitting PATH","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:17Z","receivedAt":"2017-04-26T20:19:32Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In the (admittedly, concocted) case that PATH consists only of colons, we\nwould leak the duplicated string.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 3fbfda5978b..fe0e3ccd248 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -961,8 +961,10 @@ static char **get_path_split(void)\n \t\t\t++n;\n \t\t}\n \t}\n-\tif (!n)\n+\tif (!n) {\n+\t\tfree(envpath);\n \t\treturn NULL;\n+\t}\n \n \tALLOC_ARRAY(path, n + 1);\n \tp = envpath;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317971","messageId":"ead7050c37093820e3fd097dc31bc56204eee59a.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 02/26] winansi: avoid use of uninitialized value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:21Z","receivedAt":"2017-04-26T20:19:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When stdout is not connected to a Win32 console, we incorrectly used an\nuninitialized value for the \"plain\" character attributes.\n\nDetected by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex 793420f9d0d..fd6910746c8 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -105,6 +105,8 @@ static int is_console(int fd)\n \tif (!fd) {\n \t\tif (!GetConsoleMode(hcon, &mode))\n \t\t\treturn 0;\n+\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n+\t\t\tFOREGROUND_RED;\n \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n \t\treturn 0;\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317972","messageId":"2299a84fff0232d90bdd4802bc7be15ff510a168.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 03/26] winansi: avoid buffer overrun","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:26Z","receivedAt":"2017-04-26T20:19:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we could not convert the UTF-8 sequence into Unicode for writing to\nthe Console, we should not try to write an insanely-long sequence of\ninvalid wide characters (mistaking the negative return value for an\nunsigned length).\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex fd6910746c8..861b79d8c31 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -135,6 +135,11 @@ static void write_console(unsigned char *str, size_t len)\n \n \t/* convert utf-8 to utf-16 */\n \tint wlen = xutftowcsn(wbuf, (char*) str, ARRAY_SIZE(wbuf), len);\n+\tif (wlen < 0) {\n+\t\twchar_t *err = L\"[invalid]\";\n+\t\tWriteConsoleW(console, err, wcslen(err), &dummy, NULL);\n+\t\treturn;\n+\t}\n \n \t/* write directly to console */\n \tWriteConsoleW(console, wbuf, wlen, &dummy, NULL);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317973","messageId":"8a33cecef46887328fb5b6fd846385e04281a1db.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 04/26] add_commit_patch_id(): avoid allocating memory unnecessarily","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:29Z","receivedAt":"2017-04-26T20:19:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"It would appear that we allocate (and forget to release) memory if the\npatch ID is not even defined.\n\nReported by the Coverity tool.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n patch-ids.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/patch-ids.c b/patch-ids.c\nindex fa8f11de826..92eba7a059e 100644\n--- a/patch-ids.c\n+++ b/patch-ids.c\n@@ -99,11 +99,12 @@ struct patch_id *has_commit_patch_id(struct commit *commit,\n struct patch_id *add_commit_patch_id(struct commit *commit,\n \t\t\t\t     struct patch_ids *ids)\n {\n-\tstruct patch_id *key = xcalloc(1, sizeof(*key));\n+\tstruct patch_id *key;\n \n \tif (!patch_id_defined(commit))\n \t\treturn NULL;\n \n+\tkey = xcalloc(1, sizeof(*key));\n \tif (init_patch_id_entry(key, commit, ids)) {\n \t\tfree(key);\n \t\treturn NULL;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317974","messageId":"1a12ba40a2db3925534bd2192ed8e9ab9a87215e.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:37Z","receivedAt":"2017-04-26T20:19:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we fail to read, or parse, the file, we still want to close the file\ndescriptor and release the strbuf.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/am.c | 11 ++++++-----\n 1 file changed, 6 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 805f56cec2f..01b700e5e74 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1359,15 +1359,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *fp = xfopen(mail, \"r\");\n \tconst char *x;\n+\tint ret = 0;\n \n \tif (strbuf_getline_lf(&sb, fp))\n-\t\treturn -1;\n+\t\tret = -1;\n \n-\tif (!skip_prefix(sb.buf, \"From \", &x))\n-\t\treturn -1;\n+\tif (!ret && !skip_prefix(sb.buf, \"From \", &x))\n+\t\tret = -1;\n \n-\tif (get_oid_hex(x, commit_id) < 0)\n-\t\treturn -1;\n+\tif (!ret && get_oid_hex(x, commit_id) < 0)\n+\t\tret = -1;\n \n \tstrbuf_release(&sb);\n \tfclose(fp);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317975","messageId":"d88e30ff9ada2f47b4f303269162b6e8e19b1baa.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 05/26] git_config_rename_section_in_file(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:33Z","receivedAt":"2017-04-26T20:20:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In case of errors, we really want the file descriptor to be closed.\n\nDiscovered by a Coverity scan.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.c | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/config.c b/config.c\nindex 0daaed338ea..ed1420fb096 100644\n--- a/config.c\n+++ b/config.c\n@@ -2599,7 +2599,7 @@ int git_config_rename_section_in_file(const char *config_filename,\n \tstruct lock_file *lock;\n \tint out_fd;\n \tchar buf[1024];\n-\tFILE *config_file;\n+\tFILE *config_file = NULL;\n \tstruct stat st;\n \n \tif (new_name && !section_name_is_ok(new_name)) {\n@@ -2681,11 +2681,14 @@ int git_config_rename_section_in_file(const char *config_filename,\n \t\t}\n \t}\n \tfclose(config_file);\n+\tconfig_file = NULL;\n commit_and_out:\n \tif (commit_lock_file(lock) < 0)\n \t\tret = error_errno(\"could not write config file %s\",\n \t\t\t\t  config_filename);\n out:\n+\tif (config_file)\n+\t\tfclose(config_file);\n \trollback_lock_file(lock);\n out_no_rollback:\n \tfree(filename_buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317976","messageId":"c634ea5dad0ce1c1f424f54a12a5614e6fa4a847.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 08/26] difftool: close file descriptors after reading","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:53Z","receivedAt":"2017-04-26T20:20:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Spotted by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/difftool.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex 1354d0e4625..a4f1d117ef6 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,\n \t\thashmap_entry_init(entry, strhash(buf.buf));\n \t\thashmap_add(result, entry);\n \t}\n+\tfclose(fp);\n \tif (finish_command(&diff_files))\n \t\tdie(\"diff-files did not exit properly\");\n \tstrbuf_release(&index_env);\n@@ -497,6 +498,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \t}\n \n+\tfclose(fp);\n \tif (finish_command(&child)) {\n \t\tret = error(\"error occurred running diff --raw\");\n \t\tgoto finish;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317977","messageId":"366e4d805da9b4b610fe216537de5e4a4c3941ed.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 07/26] http-backend: avoid memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:47Z","receivedAt":"2017-04-26T20:20:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n http-backend.c | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/http-backend.c b/http-backend.c\nindex eef0a361f4f..d12572fda10 100644\n--- a/http-backend.c\n+++ b/http-backend.c\n@@ -681,8 +681,10 @@ int cmd_main(int argc, const char **argv)\n \t\tif (!regexec(&re, dir, 1, out, 0)) {\n \t\t\tsize_t n;\n \n-\t\t\tif (strcmp(method, c->method))\n+\t\t\tif (strcmp(method, c->method)) {\n+\t\t\t\tfree(dir);\n \t\t\t\treturn bad_request(&hdr, c);\n+\t\t\t}\n \n \t\t\tcmd = c;\n \t\t\tn = out[0].rm_eo - out[0].rm_so;\n@@ -708,5 +710,7 @@ int cmd_main(int argc, const char **argv)\n \t\t\t\t\t   max_request_buffer);\n \n \tcmd->imp(&hdr, cmd_arg);\n+\tfree(dir);\n+\tfree(cmd_arg);\n \treturn 0;\n }\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317978","messageId":"f5a4cd0c7c3b59e6b4b062b8f8a6b4aa1420a88d.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 09/26] status: close file descriptor after reading git-rebase-todo","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:19:56Z","receivedAt":"2017-04-26T20:20:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 03754849626..0a6e16dbe0f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1168,6 +1168,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)\n \t\tabbrev_sha1_in_line(&line);\n \t\tstring_list_append(lines, line.buf);\n \t}\n+\tfclose(f);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317979","messageId":"1fb841cee32996ee9194c2bd33b9dfe74cc37726.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:16Z","receivedAt":"2017-04-26T20:20:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mailsplit.c | 2 +-\n mailinfo.c          | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\nindex 30681681c13..c0d88f97512 100644\n--- a/builtin/mailsplit.c\n+++ b/builtin/mailsplit.c\n@@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n \n \tdo {\n \t\tpeek = fgetc(f);\n-\t} while (isspace(peek));\n+\t} while (peek >= 0 && isspace(peek));\n \tungetc(peek, f);\n \n \tif (strbuf_getwholeline(&buf, f, '\\n')) {\ndiff --git a/mailinfo.c b/mailinfo.c\nindex 68037758f2f..60dcad7b714 100644\n--- a/mailinfo.c\n+++ b/mailinfo.c\n@@ -1099,7 +1099,7 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n \n \tdo {\n \t\tpeek = fgetc(mi->input);\n-\t} while (isspace(peek));\n+\t} while (peek >= 0 && isspace(peek));\n \tungetc(peek, mi->input);\n \n \t/* process the email header */\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317980","messageId":"a1381df96c940f1edf5b7fb0c49abfc7b12b72fa.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 11/26] cat-file: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:23Z","receivedAt":"2017-04-26T20:20:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/cat-file.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 1890d7a6390..9af863e7915 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \t\tdie(\"git cat-file %s: bad file\", obj_name);\n \n \twrite_or_die(1, buf, size);\n+\tfree(buf);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317981","messageId":"be7ff5f9b303bb42f0d2a6c8f144bcc8342450cc.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 12/26] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:27Z","receivedAt":"2017-04-26T20:20:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/checkout.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex bfa5419f335..98f98256608 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n \tif (!ce)\n \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n \tstatus = checkout_entry(ce, state, NULL);\n+\tfree(ce);\n \treturn status;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317982","messageId":"1f5cb7cd40ad0856dc05d92178756df6c005c69f.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 13/26] split_commit_in_progress(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:45Z","receivedAt":"2017-04-26T20:21:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 0a6e16dbe0f..1f3f6bcb980 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status *s)\n \tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n \n \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n-\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n+\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n+\t\tfree(head);\n+\t\tfree(orig_head);\n+\t\tfree(rebase_amend);\n+\t\tfree(rebase_orig_head);\n \t\treturn split_in_progress;\n+\t}\n \n \tif (!strcmp(rebase_amend, rebase_orig_head)) {\n \t\tif (strcmp(head, rebase_amend))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317983","messageId":"042b3e98e9e5b8850c35103cc56cf651b2fb3f6e.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 14/26] setup_bare_git_dir(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:48Z","receivedAt":"2017-04-26T20:21:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0309c278218..0320a9ad14c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n-\t\tconst char *gitdir;\n+\t\tstatic const char *gitdir;\n \n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317984","messageId":"ee39206e8165171c12ab8c5da9e29429b3aa166d.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 15/26] setup_discovered_git_dir(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:52Z","receivedAt":"2017-04-26T20:21:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Identified by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0320a9ad14c..12efca85a41 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n+\t\tchar *p = NULL;\n+\t\tconst char *ret;\n+\n \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n-\t\t\tgitdir = real_pathdup(gitdir, 1);\n+\t\t\tgitdir = p = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(\"Could not come back to cwd\");\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tfree(p);\n+\t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317985","messageId":"0a2500c748db356be5a5aa2829f2e37c40cefef8.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 16/26] pack-redundant: plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:20:55Z","receivedAt":"2017-04-26T20:21:17Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Identified via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/pack-redundant.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 72c815844dd..cb1df1c7614 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -442,6 +442,7 @@ static void minimize(struct pack_list **min)\n \t/* return if there are no objects missing from the unique set */\n \tif (missing->size == 0) {\n \t\t*min = unique;\n+\t\tfree(missing);\n \t\treturn;\n \t}\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317986","messageId":"517446aaef6742d546afeab2a5270f72992c2742.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 17/26] mktree: plug memory leaks reported by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:12Z","receivedAt":"2017-04-26T20:21:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mktree.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/mktree.c b/builtin/mktree.c\nindex de9b40fc63b..f0354bc9718 100644\n--- a/builtin/mktree.c\n+++ b/builtin/mktree.c\n@@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \tunsigned mode;\n \tenum object_type mode_type; /* object type derived from mode */\n \tenum object_type obj_type; /* object type derived from sha */\n-\tchar *path;\n+\tchar *path, *p = NULL;\n \tunsigned char sha1[20];\n \n \tptr = buf;\n@@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t\tstruct strbuf p_uq = STRBUF_INIT;\n \t\tif (unquote_c_style(&p_uq, path, NULL))\n \t\t\tdie(\"invalid quoting\");\n-\t\tpath = strbuf_detach(&p_uq, NULL);\n+\t\tpath = p = strbuf_detach(&p_uq, NULL);\n \t}\n \n \t/*\n@@ -136,6 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t}\n \n \tappend_to_tree(mode, sha1, path);\n+\tfree(p);\n }\n \n int cmd_mktree(int ac, const char **av, const char *prefix)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317987","messageId":"1eda2649781a15264e9995e705d19206185dbbb1.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 18/26] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:15Z","receivedAt":"2017-04-26T20:21:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by, you guessed it, Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/fast-export.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex e0220630d00..828d41c0c11 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -765,6 +765,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t       (int)(tagger_end - tagger), tagger,\n \t       tagger == tagger_end ? \"\" : \"\\n\",\n \t       (int)message_size, (int)message_size, message ? message : \"\");\n+\tfree(buf);\n }\n \n static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317988","messageId":"69b267b697cbf7f8948418e1b4d5eb52af911bf0.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 19/26] receive-pack: plug memory leak in update()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:18Z","receivedAt":"2017-04-26T20:21:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/receive-pack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f96834f42c9..48c07ddb659 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -986,7 +986,8 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstatic char *namespaced_name;\n+\tconst char *ret;\n \tstruct object_id *old_oid = &cmd->old_oid;\n \tstruct object_id *new_oid = &cmd->new_oid;\n \n@@ -997,6 +998,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t}\n \n \tstrbuf_addf(&namespaced_name_buf, \"%s%s\", get_git_namespace(), name);\n+\tfree(namespaced_name);\n \tnamespaced_name = strbuf_detach(&namespaced_name_buf, NULL);\n \n \tif (is_ref_checked_out(namespaced_name)) {\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317989","messageId":"0051da81b5cffe53122c036122402418c7f8d55f.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 20/26] line-log: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:21Z","receivedAt":"2017-04-26T20:21:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n line-log.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/line-log.c b/line-log.c\nindex a23b910471b..19d46e9ea2c 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n \tchanged = process_all_files(&parent_range, rev, &queue, range);\n \tif (parent)\n \t\tadd_line_range(rev, parent, parent_range);\n+\tfree(parent_range);\n \treturn changed;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317990","messageId":"ecb1959172d0e3b5501af64879190808f513898a.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 21/26] shallow: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:25Z","receivedAt":"2017-04-26T20:21:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n shallow.c | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/shallow.c b/shallow.c\nindex 25b6db989bf..f9370961f99 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -473,11 +473,15 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1,\n \tstruct commit_list *head = NULL;\n \tint bitmap_nr = (info->nr_bits + 31) / 32;\n \tsize_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);\n-\tuint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */\n-\tuint32_t *bitmap = paint_alloc(info);\n \tstruct commit *c = lookup_commit_reference_gently(sha1, 1);\n+\tuint32_t *tmp; /* to be freed before return */\n+\tuint32_t *bitmap;\n+\n \tif (!c)\n \t\treturn;\n+\n+\ttmp = xmalloc(bitmap_size);\n+\tbitmap = paint_alloc(info);\n \tmemset(bitmap, 0, bitmap_size);\n \tbitmap[id / 32] |= (1U << (id % 32));\n \tcommit_list_insert(c, &head);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317991","messageId":"aeb46b9436b1f5f54322cb818519db97801b9d7a.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 22/26] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:44Z","receivedAt":"2017-04-26T20:21:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"We free()d the `log` buffer when dwim_log() returned 1, but not when it\nreturned a larger value (which meant that it still allocated the buffer\nbut we simply ignored it).\n\nIdentified by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n reflog-walk.c | 6 +++++-\n 1 file changed, 5 insertions(+), 1 deletion(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 99679f58255..ec66f2b16e6 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tif (!reflogs || reflogs->nr == 0) {\n \t\t\tstruct object_id oid;\n \t\t\tchar *b;\n-\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {\n+\t\t\tint ret = dwim_log(branch, strlen(branch),\n+\t\t\t\t\t   oid.hash, &b);\n+\t\t\tif (ret > 1)\n+\t\t\t\tfree(b);\n+\t\t\telse if (ret == 1) {\n \t\t\t\tif (reflogs) {\n \t\t\t\t\tfree(reflogs->ref);\n \t\t\t\t\tfree(reflogs);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317992","messageId":"de562a0f541a8b25a14d3cf80dc677c59f795b37.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 23/26] remote: plug memory leak in match_explicit()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:48Z","receivedAt":"2017-04-26T20:21:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The `guess_ref()` returns an allocated buffer of which `make_linked_ref()`\ndoes not take custody (`alloc_ref()` makes a copy), therefore we need to\nrelease the buffer afterwards.\n\nNoticed via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n remote.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 801137c72eb..72b4591b983 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1191,9 +1191,10 @@ static int match_explicit(struct ref *src, struct ref *dst,\n \t\telse if (is_null_oid(&matched_src->new_oid))\n \t\t\terror(\"unable to delete '%s': remote ref does not exist\",\n \t\t\t      dst_value);\n-\t\telse if ((dst_guess = guess_ref(dst_value, matched_src)))\n+\t\telse if ((dst_guess = guess_ref(dst_value, matched_src))) {\n \t\t\tmatched_dst = make_linked_ref(dst_guess, dst_tail);\n-\t\telse\n+\t\t\tfree(dst_guess);\n+\t\t} else\n \t\t\terror(\"unable to push to unqualified destination: %s\\n\"\n \t\t\t      \"The destination refspec neither matches an \"\n \t\t\t      \"existing ref on the remote nor\\n\"\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317993","messageId":"f67439bafe4515179ff9dac4e5f1a325b1de6ef6.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 26/26] submodule_uses_worktrees(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:22:03Z","receivedAt":"2017-04-26T20:22:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"There is really no reason why we would need to hold onto the allocated\nstring longer than necessary.\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n worktree.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/worktree.c b/worktree.c\nindex bae787cf8d7..89a81b13de3 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -399,6 +399,7 @@ int submodule_uses_worktrees(const char *path)\n \n \t/* The env would be set for the superproject. */\n \tget_common_dir_noenv(&sb, submodule_gitdir);\n+\tfree(submodule_gitdir);\n \n \t/*\n \t * The check below is only known to be good for repository format\n@@ -418,7 +419,6 @@ int submodule_uses_worktrees(const char *path)\n \t/* See if there is any file inside the worktrees directory. */\n \tdir = opendir(sb.buf);\n \tstrbuf_release(&sb);\n-\tfree(submodule_gitdir);\n \n \tif (!dir)\n \t\treturn 0;\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"317994","messageId":"51890c396683ddc9485a44d50b8ccaf04e06a3e2.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 25/26] show_worktree(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:59Z","receivedAt":"2017-04-26T20:22:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The buffer allocated by shorten_unambiguous_ref() needs to be released.\n\nDiscovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/worktree.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 9993ded41aa..6bfd7ad5323 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -409,9 +409,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)\n \t\t\t\tfind_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));\n \t\tif (wt->is_detached)\n \t\t\tstrbuf_addstr(&sb, \"(detached HEAD)\");\n-\t\telse if (wt->head_ref)\n-\t\t\tstrbuf_addf(&sb, \"[%s]\", shorten_unambiguous_ref(wt->head_ref, 0));\n-\t\telse\n+\t\telse if (wt->head_ref) {\n+\t\t\tchar *ref = shorten_unambiguous_ref(wt->head_ref, 0);\n+\t\t\tstrbuf_addf(&sb, \"[%s]\", ref);\n+\t\t\tfree(ref);\n+\t\t} else\n \t\t\tstrbuf_addstr(&sb, \"(error)\");\n \t}\n \tprintf(\"%s\\n\", sb.buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317995","messageId":"a0c807b75ea55cf944554f4c2cd4dd4126572277.1493237937.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH 24/26] name-rev: avoid leaking memory in the `deref` case","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-26T20:21:54Z","receivedAt":"2017-04-26T20:22:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When the `name_rev()` function is asked to dereference the tip name, it\nallocates memory. But when it turns out that another tip already\ndescribed the commit better than the current one, we forgot to release\nthe memory.\n\nPointed out by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/name-rev.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 92a5d8a5d26..a4ce73fb1e9 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n \tstruct rev_name *name = (struct rev_name *)commit->util;\n \tstruct commit_list *parents;\n \tint parent_number = 1;\n+\tchar *p = NULL;\n \n \tparse_commit(commit);\n \n@@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n \t\treturn;\n \n \tif (deref) {\n-\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n+\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n \n \t\tif (generation)\n \t\t\tdie(\"generation: %d, but deref?\", generation);\n@@ -53,8 +54,10 @@ static void name_rev(struct commit *commit,\n \t\tname->taggerdate = taggerdate;\n \t\tname->generation = generation;\n \t\tname->distance = distance;\n-\t} else\n+\t} else {\n+\t\tfree(p);\n \t\treturn;\n+\t}\n \n \tfor (parents = commit->parents;\n \t\t\tparents;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"317999","messageId":"CAGZ79kbQTbFEtg7N8kpnWDhPmuVyhc-=gey7ca0XobgOwE8Q3w@mail.gmail.com","threadId":"45809","inReplyTo":"1a12ba40a2db3925534bd2192ed8e9ab9a87215e.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-04-26T21:06:09Z","receivedAt":"2017-04-26T21:06:16Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Apr 26, 2017 at 1:19 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> When we fail to read, or parse, the file, we still want to close the file\n> descriptor and release the strbuf.\n>\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/am.c | 11 ++++++-----\n>  1 file changed, 6 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/am.c b/builtin/am.c\n> index 805f56cec2f..01b700e5e74 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1359,15 +1359,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n>         struct strbuf sb = STRBUF_INIT;\n>         FILE *fp = xfopen(mail, \"r\");\n>         const char *x;\n> +       int ret = 0;\n>\n>         if (strbuf_getline_lf(&sb, fp))\n> -               return -1;\n> +               ret = -1;\n>\n> -       if (!skip_prefix(sb.buf, \"From \", &x))\n> -               return -1;\n> +       if (!ret && !skip_prefix(sb.buf, \"From \", &x))\n> +               ret = -1;\n>\n> -       if (get_oid_hex(x, commit_id) < 0)\n> -               return -1;\n> +       if (!ret && get_oid_hex(x, commit_id) < 0)\n> +               ret = -1;\n>\n\nIn similar cases of fixing mem leaks, we'd put a label here\nand make excessive use of goto, instead of setting ret to -1.\nAs \"ret\" and the commands are short, this is visually just as appealing.\n\nThanks,\nStefan\n"},{"id":"318001","messageId":"CAGZ79kaJGLQjg09WMuK6v9yPpwmFnNkDq+4Tg0O7JUYEPaCjOw@mail.gmail.com","threadId":"45809","inReplyTo":"042b3e98e9e5b8850c35103cc56cf651b2fb3f6e.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 14/26] setup_bare_git_dir(): fix memory leak","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-04-26T21:20:16Z","receivedAt":"2017-04-26T21:20:23Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Apr 26, 2017 at 1:20 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> Reported by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  setup.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/setup.c b/setup.c\n> index 0309c278218..0320a9ad14c 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n>\n>         /* --work-tree is set without --git-dir; use discovered one */\n>         if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> -               const char *gitdir;\n> +               static const char *gitdir;\n\nThis alone doesn't fix the memleak if the code were called multiple times.\nAs by having it static it will be init'd to NULL, we could introduce a\n\n    static const char *gitdir; /* must live until the end of time because ... */\n    if (!gitdir)\n        die(\"BUG: called setup_bare_git_dir twice?\");\n\nI tried looking into setup_explicit_git_dir that is called with gitdir here\nand it looks like it duplicates the memory in most cases, so maybe we\ncan even get away with no static variable here and instead either inline\nthe gitdir computation in the arguments of setup_explicit_git_dir\nor have a variable here that holds the returns of setup_explicit_git_dir\nsuch that we can free after?\n\nThanks,\nStefan\n"},{"id":"318002","messageId":"CAGZ79kbbHshh4=WC2ymG15=W5oq98b3KTV4zxiTx0LgCLeYwfQ@mail.gmail.com","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-04-26T21:34:58Z","receivedAt":"2017-04-26T21:35:26Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, Apr 26, 2017 at 1:19 PM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> I recently registered the git-for-windows fork with Coverity to ensure\n> that even the Windows-specific patches get some static analysis love.\n\nYAY! How do you trigger the coverity scan? (via travis or uploading a tarball\nmanually every once in a while?) Can you talk about the setup? I'm interested\nin that as I run coverity for Junios pu branch, plus a couple patches on top[1].\n\n[1] https://github.com/stefanbeller/git/commits/coverity\n\n>\n> While at it, I squashed a couple of obvious issues in the part that is\n> not Windows-specific.\n\nThanks.\n\n> Note: while this patch series squashes some of those issues, the\n> remaining issues are not necessarily all false positives (e.g. Coverity\n> getting fooled by our FLEX_ARRAY trick into believing that the last\n> member of the struct is indeed a 0 or 1 size array) or intentional (e.g.\n> builtins not releasing memory because exit() is called right after\n> returning from the function that leaks memory).\n\nFor the latter I think we could get away with maintaining patches on\na dedicated coverity branch (which I do currently, just not in an extensive\nmanner). For the first, I think we can just compile with FLEX_ARRAY\ndefined as an insanely large number. I'll experiment with that.\n\n> Notable examples of the remaining issues are:\n>\n> - a couple of callers of shorten_unambiguous_ref() assume that they do\n>   not have to release the memory returned from that function, often\n>   assigning the pointer to a `const` variable that typically does not\n>   hold a pointer that needs to be free()d. My hunch is that we will want\n>   to convert that function to have a fixed number of static buffers and\n>   use those in a round robin fashion à la sha1_to_hex().\n>\n> - pack-redundant.c seems to have hard-to-reason-about code paths that\n>   may eventually leak memory. Essentially, the custody of the allocated\n>   memory is not clear at all.\n>\n> - fast-import.c calls strbuf_detach() on the command_buf without any\n>   obvious rationale. Turns out that *some* code paths assign\n>   command_buf.buf to a `recent_command` which releases the buffer later.\n>   However, from a cursory look it appears to me as if there are some\n>   other code paths that skip that assignment, effectively causing a memory\n>   leak once strbuf_detach() is called.\n>\n> Sadly, I lack the time to pursue those remaining issues further.\n>\n\nThanks,\nStefan\n"},{"id":"318047","messageId":"xmqq8tmmo0q6.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"CAGZ79kbQTbFEtg7N8kpnWDhPmuVyhc-=gey7ca0XobgOwE8Q3w@mail.gmail.com","subject":"Re: [PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T05:53:21Z","receivedAt":"2017-04-27T05:53:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Stefan Beller <sbeller@google.com> writes:\n\n>> -       if (get_oid_hex(x, commit_id) < 0)\n>> -               return -1;\n>> +       if (!ret && get_oid_hex(x, commit_id) < 0)\n>> +               ret = -1;\n>>\n>\n> In similar cases of fixing mem leaks, we'd put a label here\n> and make excessive use of goto, instead of setting ret to -1.\n> As \"ret\" and the commands are short, this is visually just as appealing.\n\nI wouldn't call that visually appealing.  Fixing resource leaks is\ngood, and only because this function is short enough and the funny\nway to skip over various operation need to last for just a few\ninstructions, it is tolerable.  If the function were shorter, then\nwe may have used\n\n\tif (!strbuf_getline_lf() &&\n\t    skip_prefix() &&\n\t    !get_oid_hex())\n\t\tret = 0; /* happy */\n\telse\n\t\tret = -1;\n\trelease resources here;\n        return ret;\n\nand that would have been OK.  If longer, as you said, jumping to a\nlabel at the end of function to release the acquired resource would\nbe a lot more maintainable way than either of the above alternatives\nthat are only usable for short functions.\n\nThe patch as posted makes the function fail to return -1 when it\nfinds problems, by the way.  It needs to return \"ret\" not the\nhardcoded \"0\" at the end.\n\n\n        \n"},{"id":"318048","messageId":"xmqq4lxao0ds.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"366e4d805da9b4b610fe216537de5e4a4c3941ed.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 07/26] http-backend: avoid memory leaks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T06:00:47Z","receivedAt":"2017-04-27T06:00:54Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  http-backend.c | 6 +++++-\n>  1 file changed, 5 insertions(+), 1 deletion(-)\n>\n> diff --git a/http-backend.c b/http-backend.c\n> index eef0a361f4f..d12572fda10 100644\n> --- a/http-backend.c\n> +++ b/http-backend.c\n> @@ -681,8 +681,10 @@ int cmd_main(int argc, const char **argv)\n>  \t\tif (!regexec(&re, dir, 1, out, 0)) {\n>  \t\t\tsize_t n;\n>  \n> -\t\t\tif (strcmp(method, c->method))\n> +\t\t\tif (strcmp(method, c->method)) {\n> +\t\t\t\tfree(dir);\n>  \t\t\t\treturn bad_request(&hdr, c);\n> +\t\t\t}\n>  \n>  \t\t\tcmd = c;\n>  \t\t\tn = out[0].rm_eo - out[0].rm_so;\n> @@ -708,5 +710,7 @@ int cmd_main(int argc, const char **argv)\n>  \t\t\t\t\t   max_request_buffer);\n>  \n>  \tcmd->imp(&hdr, cmd_arg);\n> +\tfree(dir);\n> +\tfree(cmd_arg);\n>  \treturn 0;\n>  }\n\nHmph.  I find a \"leak\" of a resource acquired inside the main\nfunction and not released when the main function leaves a lot less\ninteresting than the other ones this series covers.\n\nWhen the \"return\" in the first hunk leaves the function and also\nthe same block of the if () statement breaks out the loop, we also\nfail to call regfree(&re).  Shouldn't we be cleaning it up as well?\n\n"},{"id":"318049","messageId":"xmqqzif2mlm1.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"c634ea5dad0ce1c1f424f54a12a5614e6fa4a847.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 08/26] difftool: close file descriptors after reading","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T06:05:10Z","receivedAt":"2017-04-27T06:05:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Spotted by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/difftool.c | 2 ++\n>  1 file changed, 2 insertions(+)\n>\n> diff --git a/builtin/difftool.c b/builtin/difftool.c\n> index 1354d0e4625..a4f1d117ef6 100644\n> --- a/builtin/difftool.c\n> +++ b/builtin/difftool.c\n> @@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,\n>  \t\thashmap_entry_init(entry, strhash(buf.buf));\n>  \t\thashmap_add(result, entry);\n>  \t}\n> +\tfclose(fp);\n>  \tif (finish_command(&diff_files))\n>  \t\tdie(\"diff-files did not exit properly\");\n>  \tstrbuf_release(&index_env);\n\nThis one looks sensible.\n\n> @@ -497,6 +498,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n>  \t\t}\n>  \t}\n>  \n> +\tfclose(fp);\n\nThe huge loop we see in the pre-context of this hunk has many\n\"return\"s and \"goto finish\"es that can leave fp still open; while\nthis patch does not hurt, it is probably somewhat insufficient.\n\n>  \tif (finish_command(&child)) {\n>  \t\tret = error(\"error occurred running diff --raw\");\n>  \t\tgoto finish;\n"},{"id":"318050","messageId":"xmqqshkumlhw.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"1fb841cee32996ee9194c2bd33b9dfe74cc37726.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T06:07:39Z","receivedAt":"2017-04-27T06:07:47Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/mailsplit.c | 2 +-\n>  mailinfo.c          | 2 +-\n>  2 files changed, 2 insertions(+), 2 deletions(-)\n\nGood find.  I'd retitle with a prefix\n\n\tmailinfo & mailsplit: check for EOF while parsing\n\nso that it is clear that this patch is about lower level machinery\n(as oppose to something like \"git am\").\n\nThanks.\n\n>\n> diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> index 30681681c13..c0d88f97512 100644\n> --- a/builtin/mailsplit.c\n> +++ b/builtin/mailsplit.c\n> @@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n>  \n>  \tdo {\n>  \t\tpeek = fgetc(f);\n> -\t} while (isspace(peek));\n> +\t} while (peek >= 0 && isspace(peek));\n>  \tungetc(peek, f);\n>  \n>  \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n> diff --git a/mailinfo.c b/mailinfo.c\n> index 68037758f2f..60dcad7b714 100644\n> --- a/mailinfo.c\n> +++ b/mailinfo.c\n> @@ -1099,7 +1099,7 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n>  \n>  \tdo {\n>  \t\tpeek = fgetc(mi->input);\n> -\t} while (isspace(peek));\n> +\t} while (peek >= 0 && isspace(peek));\n>  \tungetc(peek, mi->input);\n>  \n>  \t/* process the email header */\n"},{"id":"318051","messageId":"xmqqo9vimldf.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"a1381df96c940f1edf5b7fb0c49abfc7b12b72fa.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 11/26] cat-file: fix memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T06:10:20Z","receivedAt":"2017-04-27T06:10:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Discovered by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/cat-file.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/builtin/cat-file.c b/builtin/cat-file.c\n> index 1890d7a6390..9af863e7915 100644\n> --- a/builtin/cat-file.c\n> +++ b/builtin/cat-file.c\n> @@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n>  \t\tdie(\"git cat-file %s: bad file\", obj_name);\n>  \n>  \twrite_or_die(1, buf, size);\n> +\tfree(buf);\n>  \treturn 0;\n>  }\n\nThis is a border-line \"Meh\".  Just like we do not free resources\nimmediately before calling die(), we can leave this as-is as the\nonly thing that happens after this is a return from cmd_cat_file()\nback to main() that exits.\n\nThe patch is not wrong per-se, so I've applied it anyway, though.\n\nThanks.\n"},{"id":"318052","messageId":"ac257961-3133-0de4-d918-cfb8da8fbf89@kdbg.org","threadId":"45809","inReplyTo":"1a12ba40a2db3925534bd2192ed8e9ab9a87215e.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T06:14:13Z","receivedAt":"2017-04-27T06:14:28Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:19 schrieb Johannes Schindelin:\n> When we fail to read, or parse, the file, we still want to close the file\n> descriptor and release the strbuf.\n>\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/am.c | 11 ++++++-----\n>  1 file changed, 6 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/am.c b/builtin/am.c\n> index 805f56cec2f..01b700e5e74 100644\n> --- a/builtin/am.c\n> +++ b/builtin/am.c\n> @@ -1359,15 +1359,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n>  \tstruct strbuf sb = STRBUF_INIT;\n>  \tFILE *fp = xfopen(mail, \"r\");\n>  \tconst char *x;\n> +\tint ret = 0;\n>\n>  \tif (strbuf_getline_lf(&sb, fp))\n> -\t\treturn -1;\n> +\t\tret = -1;\n>\n> -\tif (!skip_prefix(sb.buf, \"From \", &x))\n> -\t\treturn -1;\n> +\tif (!ret && !skip_prefix(sb.buf, \"From \", &x))\n> +\t\tret = -1;\n>\n> -\tif (get_oid_hex(x, commit_id) < 0)\n> -\t\treturn -1;\n> +\tif (!ret && get_oid_hex(x, commit_id) < 0)\n> +\t\tret = -1;\n>\n>  \tstrbuf_release(&sb);\n>  \tfclose(fp);\n>\n\nYou forgot to 'return ret;', didn't you?\n\n-- Hannes\n\n"},{"id":"318053","messageId":"6cc5670f-2de3-33f2-3c85-5a6d99fcca12@kdbg.org","threadId":"45809","inReplyTo":"1fb841cee32996ee9194c2bd33b9dfe74cc37726.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T06:20:32Z","receivedAt":"2017-04-27T06:20:51Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:20 schrieb Johannes Schindelin:\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/mailsplit.c | 2 +-\n>  mailinfo.c          | 2 +-\n>  2 files changed, 2 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> index 30681681c13..c0d88f97512 100644\n> --- a/builtin/mailsplit.c\n> +++ b/builtin/mailsplit.c\n> @@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n>\n>  \tdo {\n>  \t\tpeek = fgetc(f);\n> -\t} while (isspace(peek));\n> +\t} while (peek >= 0 && isspace(peek));\n>  \tungetc(peek, f);\n>\n>  \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n> diff --git a/mailinfo.c b/mailinfo.c\n> index 68037758f2f..60dcad7b714 100644\n> --- a/mailinfo.c\n> +++ b/mailinfo.c\n> @@ -1099,7 +1099,7 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n>\n>  \tdo {\n>  \t\tpeek = fgetc(mi->input);\n> -\t} while (isspace(peek));\n> +\t} while (peek >= 0 && isspace(peek));\n>  \tungetc(peek, mi->input);\n>\n>  \t/* process the email header */\n>\n\nWhy? isspace(EOF) is well-defined.\n\n-- Hannes\n\n"},{"id":"318054","messageId":"20170427062114.p367j6rojnw4aj5r@sigill.intra.peff.net","threadId":"45809","inReplyTo":"1fb841cee32996ee9194c2bd33b9dfe74cc37726.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-04-27T06:21:14Z","receivedAt":"2017-04-27T06:21:22Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, Apr 26, 2017 at 10:20:16PM +0200, Johannes Schindelin wrote:\n\n> diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> index 30681681c13..c0d88f97512 100644\n> --- a/builtin/mailsplit.c\n> +++ b/builtin/mailsplit.c\n> @@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n>  \n>  \tdo {\n>  \t\tpeek = fgetc(f);\n> -\t} while (isspace(peek));\n> +\t} while (peek >= 0 && isspace(peek));\n>  \tungetc(peek, f);\n\nAre we guaranteed that EOF is a negative number?  Also, what is the\nbehavior of ungetc when we pass it EOF?\n\nIt looks like POSIX does what we want (pushing EOF is a noop, and the\nstream retains its feof() status), but I don't know if there are other\nimplementations to worry about.\n\nPerhaps:\n\n  /* soak up whitespace */\n  while ((peek = fgetc(f)) != EOF) {\n\tif (!isspace(peek)) {\n\t\tungetc(peek, f);\n\t\tbreak;\n\t}\n  }\n\nwould be more portable.\n\n-Peff\n"},{"id":"318055","messageId":"51f2bd16-7c55-7ba0-c963-6f725b2f79e5@kdbg.org","threadId":"45809","inReplyTo":"042b3e98e9e5b8850c35103cc56cf651b2fb3f6e.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 14/26] setup_bare_git_dir(): fix memory leak","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T06:27:41Z","receivedAt":"2017-04-27T06:28:04Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:20 schrieb Johannes Schindelin:\n> Reported by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  setup.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/setup.c b/setup.c\n> index 0309c278218..0320a9ad14c 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n>\n>  \t/* --work-tree is set without --git-dir; use discovered one */\n>  \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> -\t\tconst char *gitdir;\n> +\t\tstatic const char *gitdir;\n>\n>  \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n>  \t\tif (chdir(cwd->buf))\n>\n\nWhoa! Look what values are assigned to the variable: Either a static \nstring or allocated memory. I suspect that this does not fix a memory \nleak at all, but only shuts up Coverity.\n\n-- Hannes\n\nPS: stopping here as I'm running out of time.\n\n"},{"id":"318057","messageId":"xmqqk266mjzv.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"be7ff5f9b303bb42f0d2a6c8f144bcc8342450cc.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 12/26] checkout: fix memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-04-27T06:40:04Z","receivedAt":"2017-04-27T06:40:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Discovered via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/checkout.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index bfa5419f335..98f98256608 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n>  \tif (!ce)\n>  \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n>  \tstatus = checkout_entry(ce, state, NULL);\n> +\tfree(ce);\n>  \treturn status;\n>  }\n\nThanks for spotting this one and fixing it.  \n\nIn case anybody is wondering what the \"only to leak\" comment before\nthis part of the code is about (which by the way may need to be\nupdated, as the bulk of its reasoning still applies but at least we\nare no longer leaking with this patch), back when this code was\nwritten in 2008 or so it wasn't kosher to free cache_entry under\ncertain conditions, but it has been a long time since it became OK\nto free any cache entries in later 2011---we should have done this a\nlong time ago.\n\n\n\n"},{"id":"318073","messageId":"885f5dbc-b5d0-5113-d2ee-e9bac47c4271@kdbg.org","threadId":"45809","inReplyTo":"1eda2649781a15264e9995e705d19206185dbbb1.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 18/26] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T16:39:07Z","receivedAt":"2017-04-27T16:39:17Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> Reported by, you guessed it, Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/fast-export.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n> index e0220630d00..828d41c0c11 100644\n> --- a/builtin/fast-export.c\n> +++ b/builtin/fast-export.c\n> @@ -765,6 +765,7 @@ static void handle_tag(const char *name, struct tag *tag)\n>  \t       (int)(tagger_end - tagger), tagger,\n>  \t       tagger == tagger_end ? \"\" : \"\\n\",\n>  \t       (int)message_size, (int)message_size, message ? message : \"\");\n> +\tfree(buf);\n>  }\n>\n>  static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)\n>\n\nThere is an early return in the function that is not covered by this \npatch. Look for \"case DROP\".\n\n-- Hannes\n\n"},{"id":"318076","messageId":"4ae94881-305f-380b-e786-c7f4ea5735e3@kdbg.org","threadId":"45809","inReplyTo":"0051da81b5cffe53122c036122402418c7f8d55f.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 20/26] line-log: avoid memory leak","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T17:14:02Z","receivedAt":"2017-04-27T17:14:25Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> Discovered by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  line-log.c | 1 +\n>  1 file changed, 1 insertion(+)\n>\n> diff --git a/line-log.c b/line-log.c\n> index a23b910471b..19d46e9ea2c 100644\n> --- a/line-log.c\n> +++ b/line-log.c\n> @@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n>  \tchanged = process_all_files(&parent_range, rev, &queue, range);\n>  \tif (parent)\n>  \t\tadd_line_range(rev, parent, parent_range);\n> +\tfree(parent_range);\n>  \treturn changed;\n>  }\n>\n>\n\nparent_range is of type struct line_log_data *, which needs more than a \nmere free(). I think it's free_line_log_data(parent_range).\n\n-- Hannes\n\n"},{"id":"318077","messageId":"74da6153-2ce4-4224-d8d4-5be7481431ef@kdbg.org","threadId":"45809","inReplyTo":"aeb46b9436b1f5f54322cb818519db97801b9d7a.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 22/26] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T17:24:20Z","receivedAt":"2017-04-27T17:24:28Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> We free()d the `log` buffer when dwim_log() returned 1, but not when it\n> returned a larger value (which meant that it still allocated the buffer\n> but we simply ignored it).\n>\n> Identified by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  reflog-walk.c | 6 +++++-\n>  1 file changed, 5 insertions(+), 1 deletion(-)\n>\n> diff --git a/reflog-walk.c b/reflog-walk.c\n> index 99679f58255..ec66f2b16e6 100644\n> --- a/reflog-walk.c\n> +++ b/reflog-walk.c\n> @@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n>  \t\tif (!reflogs || reflogs->nr == 0) {\n>  \t\t\tstruct object_id oid;\n>  \t\t\tchar *b;\n> -\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {\n> +\t\t\tint ret = dwim_log(branch, strlen(branch),\n> +\t\t\t\t\t   oid.hash, &b);\n> +\t\t\tif (ret > 1)\n> +\t\t\t\tfree(b);\n> +\t\t\telse if (ret == 1) {\n>  \t\t\t\tif (reflogs) {\n>  \t\t\t\t\tfree(reflogs->ref);\n>  \t\t\t\t\tfree(reflogs);\n>\n\nRight after this hunk, there is another conditional that looks like it \nforgets to free reflogs.\n\n-- Hannes\n\n"},{"id":"318078","messageId":"966db3c1-a2e4-1309-e178-b885d2a1108f@kdbg.org","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Sixt","fromEmail":"j6t@kdbg.org","sentAt":"2017-04-27T17:36:32Z","receivedAt":"2017-04-27T17:36:39Z","isPatch":true,"sender":{"key":"j6t@kdbg.org","avatar":"https://avatars.githubusercontent.com/u/14810926?v=4"},"body":"Am 26.04.2017 um 22:19 schrieb Johannes Schindelin:\n> I recently registered the git-for-windows fork with Coverity to ensure\n> that even the Windows-specific patches get some static analysis love.\n>\n> While at it, I squashed a couple of obvious issues in the part that is\n> not Windows-specific.\n\nThanks for the fish. I'd looked at the series and had a few comments.\n\nHunting memory leaks is the way to insanity. Never again am I going to \nhelp with this. I prefer to rewrite this codebase to C++ and have \nleak-free code by design.\n\nThanks,\n-- Hannes\n\n"},{"id":"318103","messageId":"alpine.DEB.2.20.1704280010160.3480@virtualbox","threadId":"45809","inReplyTo":"CAGZ79kbbHshh4=WC2ymG15=W5oq98b3KTV4zxiTx0LgCLeYwfQ@mail.gmail.com","subject":"Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-27T22:50:43Z","receivedAt":"2017-04-27T22:51:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\nOn Wed, 26 Apr 2017, Stefan Beller wrote:\n\n> On Wed, Apr 26, 2017 at 1:19 PM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n> > I recently registered the git-for-windows fork with Coverity to ensure\n> > that even the Windows-specific patches get some static analysis love.\n> \n> YAY! How do you trigger the coverity scan?\n\nFor starters, I did everything manually. But I already have the grand plan\nto use VSTS build (I do not want to advertise this system too blatantly,\nbut I have to say that I really love working with that system, it is so\nmuch more powerful than Travis or AppVeyor, Jenkins comes closer but not\nby far).\n\nAs you may have glimpsed in one of my mails, Git for Windows needs a very\nspecial and extensive build setup. I call it the \"Git for Windows SDK\",\nand what it is, in a nutshell, is a custom MSYS2 installation that has all\nthe packages installed that are needed to build Git for Windows, its most\nimportant dependencies, and to bundle everything in an installer. Think of\nMSYS2 as something like Homebrew. But cozier, as it really lives inside\nits own directory tree, its /etc/ is not really visible to any other\nsoftware, for example.\n\nThis makes Continuous Testing a bit of a challenge, as you cannot hammer\nthe package repository of MSYS2 with tons of fresh full installations all\nthe time (that package repository is run by a volunteer, and it is\nsometimes unreachable, too).\n\nSo after talking to a GitHub guy at the Developer Summit during GitMerge\n(Patrick asked a couple of questions and then said my plan was okay), I\nput two new repositories up that host the initialized Git for Windows\nSDKs (one for 32-bit, one for 64-bit).\n\nAnd of course there is a job to keep them up-to-date, run once every 24h.\n\nAlmost all of the VSTS builds I maintain clone or update one or both of\nthese repositories.\n\nAnd so will also the Coverity job.\n\nI still have to find the time to figure out one more detail: how to\ndownload and extract the Coverity tool (the .zip archive has a variable\nname for the top-level directory), and doing that only every once\nin a while, say, only when there is no previously unpacked tool, or it is\nalready 4 weeks old.\n\nAnd then I should probably try to figure out a way how to delay subsequent\nruns of that job so that we run it at most once every twenty-four hours.\n\nCiao,\nDscho\n"},{"id":"318105","messageId":"alpine.DEB.2.20.1704280052410.3480@virtualbox","threadId":"45809","inReplyTo":"CAGZ79kaJGLQjg09WMuK6v9yPpwmFnNkDq+4Tg0O7JUYEPaCjOw@mail.gmail.com","subject":"Re: [PATCH 14/26] setup_bare_git_dir(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-27T22:54:13Z","receivedAt":"2017-04-27T22:54:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\nOn Wed, 26 Apr 2017, Stefan Beller wrote:\n\n> On Wed, Apr 26, 2017 at 1:20 PM, Johannes Schindelin\n> <johannes.schindelin@gmx.de> wrote:\n> > Reported by Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  setup.c | 2 +-\n> >  1 file changed, 1 insertion(+), 1 deletion(-)\n> >\n> > diff --git a/setup.c b/setup.c\n> > index 0309c278218..0320a9ad14c 100644\n> > --- a/setup.c\n> > +++ b/setup.c\n> > @@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n> >\n> >         /* --work-tree is set without --git-dir; use discovered one */\n> >         if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> > -               const char *gitdir;\n> > +               static const char *gitdir;\n> \n> This alone doesn't fix the memleak if the code were called multiple times.\n> As by having it static it will be init'd to NULL, we could introduce a\n> \n>     static const char *gitdir; /* must live until the end of time because ... */\n>     if (!gitdir)\n>         die(\"BUG: called setup_bare_git_dir twice?\");\n> \n> I tried looking into setup_explicit_git_dir that is called with gitdir here\n> and it looks like it duplicates the memory in most cases, so maybe we\n> can even get away with no static variable here and instead either inline\n> the gitdir computation in the arguments of setup_explicit_git_dir\n> or have a variable here that holds the returns of setup_explicit_git_dir\n> such that we can free after?\n\nsetup_bare_git_directory() is called by setup_git_directory(), and that\nlatter function is not reentrant. If you call setup_git_directory()\nmultiple times, it will wreak havoc, as e.g. the second time the prefix\ncannot be determined correctly because we chdir()ed up into the top-level\ndirectory.\n\nSo I am not worried about this new static, it is essentially a singleton.\n\nCiao,\nDscho\n"},{"id":"318106","messageId":"alpine.DEB.2.20.1704280056070.3480@virtualbox","threadId":"45809","inReplyTo":"51f2bd16-7c55-7ba0-c963-6f725b2f79e5@kdbg.org","subject":"Re: [PATCH 14/26] setup_bare_git_dir(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-27T22:57:08Z","receivedAt":"2017-04-27T22:57:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:20 schrieb Johannes Schindelin:\n> > Reported by Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  setup.c | 2 +-\n> >  1 file changed, 1 insertion(+), 1 deletion(-)\n> >\n> > diff --git a/setup.c b/setup.c\n> > index 0309c278218..0320a9ad14c 100644\n> > --- a/setup.c\n> > +++ b/setup.c\n> > @@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf\n> > *cwd, int offset,\n> >\n> >   /* --work-tree is set without --git-dir; use discovered one */\n> >   if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> > -\t\tconst char *gitdir;\n> > +\t\tstatic const char *gitdir;\n> >\n> >    gitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n> >    if (chdir(cwd->buf))\n> >\n> \n> Whoa! Look what values are assigned to the variable: Either a static string or\n> allocated memory. I suspect that this does not fix a memory leak at all, but\n> only shuts up Coverity.\n> \n> -- Hannes\n> \n> PS: stopping here as I'm running out of time.\n\nSorry, I meant to amend the commit message and forgot before sending the\nfirst time: setup_git_directory() (and consequently, setup_bare_git_dir())\ncan only be called once.\n\nYes, this patch is here to shut up Coverity, as it cannot know that we are\ntalking about a singleton here.\n\nCiao,\nDscho\n"},{"id":"318133","messageId":"alpine.DEB.2.20.1704281117040.3480@virtualbox","threadId":"45809","inReplyTo":"xmqq4lxao0ds.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 07/26] http-backend: avoid memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T09:40:01Z","receivedAt":"2017-04-28T09:41:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Reported via Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  http-backend.c | 6 +++++-\n> >  1 file changed, 5 insertions(+), 1 deletion(-)\n> >\n> > diff --git a/http-backend.c b/http-backend.c\n> > index eef0a361f4f..d12572fda10 100644\n> > --- a/http-backend.c\n> > +++ b/http-backend.c\n> > @@ -681,8 +681,10 @@ int cmd_main(int argc, const char **argv)\n> >  \t\tif (!regexec(&re, dir, 1, out, 0)) {\n> >  \t\t\tsize_t n;\n> >  \n> > -\t\t\tif (strcmp(method, c->method))\n> > +\t\t\tif (strcmp(method, c->method)) {\n> > +\t\t\t\tfree(dir);\n> >  \t\t\t\treturn bad_request(&hdr, c);\n> > +\t\t\t}\n> >  \n> >  \t\t\tcmd = c;\n> >  \t\t\tn = out[0].rm_eo - out[0].rm_so;\n> > @@ -708,5 +710,7 @@ int cmd_main(int argc, const char **argv)\n> >  \t\t\t\t\t   max_request_buffer);\n> >  \n> >  \tcmd->imp(&hdr, cmd_arg);\n> > +\tfree(dir);\n> > +\tfree(cmd_arg);\n> >  \treturn 0;\n> >  }\n> \n> Hmph.  I find a \"leak\" of a resource acquired inside the main\n> function and not released when the main function leaves a lot less\n> interesting than the other ones this series covers.\n\nAh, I missed that this falls squarely into the \"one-shot programs are\nallowed to be sloppy in their memory management, essentially using exit()\nas garbage collector\" category.\n\nWill drop,\nDscho\n"},{"id":"318134","messageId":"alpine.DEB.2.20.1704281146030.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqzif2mlm1.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 08/26] difftool: close file descriptors after reading","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T09:51:22Z","receivedAt":"2017-04-28T09:52:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> > diff --git a/builtin/difftool.c b/builtin/difftool.c\n> > index 1354d0e4625..a4f1d117ef6 100644\n> > --- a/builtin/difftool.c\n> > +++ b/builtin/difftool.c\n> > @@ -497,6 +498,7 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n> >  \t\t}\n> >  \t}\n> >  \n> > +\tfclose(fp);\n> \n> The huge loop we see in the pre-context of this hunk has many\n> \"return\"s and \"goto finish\"es that can leave fp still open; while\n> this patch does not hurt, it is probably somewhat insufficient.\n\nYou are absolutely correct, and I am somewhat surprised that Coverity did\nnot complain more loudly.\n\nTBH I really only tried to address these fixes on the cheap, as my main\naim was to get to the critical bugs in the Windows-specific part (I did\nnot find anything major, though). Therefore, I only looked at what\nCoverity labels as the \"high impact\" issues. The leaks in the loop that\nyou pointed out may be labeled as minor by Coverity.\n\nI also noticed that a couple of error messages have not been marked as\ntranslateable, I must have forgotten that before submitting the difftool\npatch series :-(\n\nIn any case, in the next iteration of this patch series, this patch will\nconvert all returns to `ret = ...; goto finish;` calls, and fclose(fp)\nthere unless it has been closed already.\n\nThanks,\nDscho\n"},{"id":"318135","messageId":"alpine.DEB.2.20.1704281155080.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqshkumlhw.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T09:55:27Z","receivedAt":"2017-04-28T09:55:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Reported via Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  builtin/mailsplit.c | 2 +-\n> >  mailinfo.c          | 2 +-\n> >  2 files changed, 2 insertions(+), 2 deletions(-)\n> \n> Good find.  I'd retitle with a prefix\n> \n> \tmailinfo & mailsplit: check for EOF while parsing\n> \n> so that it is clear that this patch is about lower level machinery\n> (as oppose to something like \"git am\").\n\nTrue. Will be fixed in the next iteration,\nDscho\n"},{"id":"318136","messageId":"alpine.DEB.2.20.1704281155520.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqo9vimldf.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 11/26] cat-file: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T09:59:31Z","receivedAt":"2017-04-28T09:59:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Discovered by Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  builtin/cat-file.c | 1 +\n> >  1 file changed, 1 insertion(+)\n> >\n> > diff --git a/builtin/cat-file.c b/builtin/cat-file.c\n> > index 1890d7a6390..9af863e7915 100644\n> > --- a/builtin/cat-file.c\n> > +++ b/builtin/cat-file.c\n> > @@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n> >  \t\tdie(\"git cat-file %s: bad file\", obj_name);\n> >  \n> >  \twrite_or_die(1, buf, size);\n> > +\tfree(buf);\n> >  \treturn 0;\n> >  }\n> \n> This is a border-line \"Meh\".  Just like we do not free resources\n> immediately before calling die(), we can leave this as-is as the\n> only thing that happens after this is a return from cmd_cat_file()\n> back to main() that exits.\n\nIf you are mostly concerned about the status quo, that is true.\n\nI am a lot more concerned with future changes, where we may easily decide\nthat it is time to move a file-local function out of its hiding place and\nmake it more usable.\n\nFrom that perspective, it is one thing to have a blatant memory leak in a\ncmd_*() function, and it is an entirely different matter to have such a\nleak in a function that happens to be called only from cmd_*() functions:\nsomebody familiar enough with Git's coding conventions (such as myself)\nwill *expect* cmd_*() to have leaks left and right and pay attention when\nlibifying that code, but be a lot less concerned about such leaks in other\nfunctions.\n\nAnd of course this concerns me more than you, as I am still trying to\ndrive forward the effort to convert more scripts into builtins.\n\nSo on my own behalf: thank you for accepting this patch.\n\nCiao,\nDscho\n"},{"id":"318137","messageId":"alpine.DEB.2.20.1704281201570.3480@virtualbox","threadId":"45809","inReplyTo":"ac257961-3133-0de4-d918-cfb8da8fbf89@kdbg.org","subject":"Re: [PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T10:02:18Z","receivedAt":"2017-04-28T10:02:39Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:19 schrieb Johannes Schindelin:\n> >\n> > diff --git a/builtin/am.c b/builtin/am.c\n> > index 805f56cec2f..01b700e5e74 100644\n> > --- a/builtin/am.c\n> > +++ b/builtin/am.c\n> > @@ -1359,15 +1359,16 @@ static int get_mail_commit_oid(struct object_id\n> > *commit_id, const char *mail)\n> >   struct strbuf sb = STRBUF_INIT;\n> >   FILE *fp = xfopen(mail, \"r\");\n> >   const char *x;\n> > +\tint ret = 0;\n> >\n> > \tif (strbuf_getline_lf(&sb, fp))\n> > -\t\treturn -1;\n> > +\t\tret = -1;\n> >\n> > -\tif (!skip_prefix(sb.buf, \"From \", &x))\n> > -\t\treturn -1;\n> > +\tif (!ret && !skip_prefix(sb.buf, \"From \", &x))\n> > +\t\tret = -1;\n> >\n> > -\tif (get_oid_hex(x, commit_id) < 0)\n> > -\t\treturn -1;\n> > +\tif (!ret && get_oid_hex(x, commit_id) < 0)\n> > +\t\tret = -1;\n> >\n> >   strbuf_release(&sb);\n> >   fclose(fp);\n> >\n> \n> You forgot to 'return ret;', didn't you?\n\nI sure did!\n\nThanks,\nDscho\n"},{"id":"318139","messageId":"alpine.DEB.2.20.1704281206500.3480@virtualbox","threadId":"45809","inReplyTo":"6cc5670f-2de3-33f2-3c85-5a6d99fcca12@kdbg.org","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T10:41:02Z","receivedAt":"2017-04-28T10:41:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:20 schrieb Johannes Schindelin:\n>\n> > diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> > index 30681681c13..c0d88f97512 100644\n> > --- a/builtin/mailsplit.c\n> > +++ b/builtin/mailsplit.c\n> > @@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir,\n> > int allow_bare,\n> >\n> >   do {\n> > \t\tpeek = fgetc(f);\n> > -\t} while (isspace(peek));\n> > +\t} while (peek >= 0 && isspace(peek));\n> >   ungetc(peek, f);\n> >\n> > \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n> > diff --git a/mailinfo.c b/mailinfo.c\n> > index 68037758f2f..60dcad7b714 100644\n> > --- a/mailinfo.c\n> > +++ b/mailinfo.c\n> > @@ -1099,7 +1099,7 @@ int mailinfo(struct mailinfo *mi, const char *msg,\n> > const char *patch)\n> >\n> >   do {\n> > \t\tpeek = fgetc(mi->input);\n> > -\t} while (isspace(peek));\n> > +\t} while (peek >= 0 && isspace(peek));\n> >   ungetc(peek, mi->input);\n> >\n> >   /* process the email header */\n> >\n> \n> Why? isspace(EOF) is well-defined.\n\nSo let's look at the man page on Linux:\n\n\tThese functions check whether c,  which  must  have  the  value  of  an\n\tunsigned char or EOF, [...]\n\nThat is the only mention of it. I find it highly unobvious whether EOF\nshould be treated as a space or not. So let's look at the MSDN page\n(https://msdn.microsoft.com/en-us/library/y13z34da.aspx) whether they talk\nmore about EOF:\n\n\tThe behavior of isspace and _isspace_l is undefined if c is not\n\tEOF or in the range 0 through 0xFF, inclusive.\n\nThat's it. So I kind of *guess* that EOF is treated as not being a\nwhitespace character (why does this make me think of politics now? Focus,\nJohannes, focus...). But the mathematician in me protests: why would we\nbe able to decide the character class of a character that does not exist?\n\nTechnically, you are correct, of course. The specs of fgetc() specify\nquite clearly that either an unsigned char cast to an int is returned, or\nEOF on end-of-file *or error*. And a quick test verifies that isspace(EOF)\nreturns 0.\n\nBut then, I guess I misunderstood what Coverity complained about: maybe\nthe problem was not so much the isspace() call but that EOF is not being\nhandled correctly. We pass it, unchecked, to ungetc().\n\nIt appears that I (or Coverity, if you will), missed another instance\nwhere we simply passed EOF unchecked to ungetc().\n\nThe next iteration will have it completely reworked: I no longer guard the\nisspace() behind an `!= EOF` check, but rather handle an early EOF as I\nthink it should be handled. Extra eyes very welcome (this is the fixup!\npatch):\n\n-- snip --\ndiff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\nindex c0d88f97512..9b3efc8e987 100644\n--- a/builtin/mailsplit.c\n+++ b/builtin/mailsplit.c\n@@ -232,8 +232,9 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n \n \tdo {\n \t\tpeek = fgetc(f);\n-\t} while (peek >= 0 && isspace(peek));\n-\tungetc(peek, f);\n+\t} while (isspace(peek));\n+\tif (peek != EOF)\n+\t\tungetc(peek, f);\n \n \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n \t\t/* empty stdin is OK */\ndiff --git a/mailinfo.c b/mailinfo.c\nindex 60dcad7b714..a319911b510 100644\n--- a/mailinfo.c\n+++ b/mailinfo.c\n@@ -882,7 +882,10 @@ static int read_one_header_line(struct strbuf *line, FILE *in)\n \tfor (;;) {\n \t\tint peek;\n \n-\t\tpeek = fgetc(in); ungetc(peek, in);\n+\t\tpeek = fgetc(in);\n+\t\tif (peek == EOF)\n+\t\t\tbreak;\n+\t\tungetc(peek, in);\n \t\tif (peek != ' ' && peek != '\\t')\n \t\t\tbreak;\n \t\tif (strbuf_getline_lf(&continuation, in))\n@@ -1094,14 +1097,18 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n \t\treturn -1;\n \t}\n \n-\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n-\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n-\n \tdo {\n \t\tpeek = fgetc(mi->input);\n-\t} while (peek >= 0 && isspace(peek));\n+\t\tif (peek == EOF) {\n+\t\t\tfclose(cmitmsg);\n+\t\t\treturn error(\"empty patch: '%s'\", patch);\n+\t\t}\n+\t} while (isspace(peek));\n \tungetc(peek, mi->input);\n \n+\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n+\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n+\n \t/* process the email header */\n \twhile (read_one_header_line(&line, mi->input))\n \t\tcheck_header(mi, &line, mi->p_hdr_data, 1);\n-- snap --\n\nIn the first hunk, I simply rely on the code after ungetc() to figure out\nthat there are no headers and to handle that case as before.\n\nThe second hunk handles the case where looking for a continuation line in\nthe header section hits EOF; it is still a valid header, but we should\navoid ungetc(EOF) to allow the next read to report EOF correctly.\n\nThe third hunk moves the malloc()s around so that we can complain about an\nempty patch, close the file and return an error value without leaking\nmemory.\n\nCiao,\nDscho\n"},{"id":"318140","messageId":"alpine.DEB.2.20.1704281241260.3480@virtualbox","threadId":"45809","inReplyTo":"20170427062114.p367j6rojnw4aj5r@sigill.intra.peff.net","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T10:44:52Z","receivedAt":"2017-04-28T10:45:10Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Peff,\n\nOn Thu, 27 Apr 2017, Jeff King wrote:\n\n> On Wed, Apr 26, 2017 at 10:20:16PM +0200, Johannes Schindelin wrote:\n> \n> > diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> > index 30681681c13..c0d88f97512 100644\n> > --- a/builtin/mailsplit.c\n> > +++ b/builtin/mailsplit.c\n> > @@ -232,7 +232,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n> >  \n> >  \tdo {\n> >  \t\tpeek = fgetc(f);\n> > -\t} while (isspace(peek));\n> > +\t} while (peek >= 0 && isspace(peek));\n> >  \tungetc(peek, f);\n> \n> Are we guaranteed that EOF is a negative number?\n\nNo, you're right.\n\n> Also, what is the behavior of ungetc when we pass it EOF?\n\nAccording to the documentation, it would cast EOF to an unsigned char and\npush that back. Definitely incorrect.\n\n> It looks like POSIX does what we want (pushing EOF is a noop, and the\n> stream retains its feof() status), but I don't know if there are other\n> implementations to worry about.\n\nThat's not what my man page here says:\n\n\tungetc()  pushes  c  back to stream, cast to unsigned char, where\n\tit is available for subsequent read operations.  Pushed-back\n\tcharacters will be returned in reverse order; only one pushback is\n\tguaranteed.\n\n> Perhaps:\n> \n>   /* soak up whitespace */\n>   while ((peek = fgetc(f)) != EOF) {\n> \tif (!isspace(peek)) {\n> \t\tungetc(peek, f);\n> \t\tbreak;\n> \t}\n>   }\n> \n> would be more portable.\n\nTrue. I changed it slightly differently, please see my reply to Hannes.\n\nThanks,\nDscho\n"},{"id":"318141","messageId":"alpine.DEB.2.20.1704281247540.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqk266mjzv.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 12/26] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T10:51:21Z","receivedAt":"2017-04-28T10:51:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Discovered via Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  builtin/checkout.c | 1 +\n> >  1 file changed, 1 insertion(+)\n> >\n> > diff --git a/builtin/checkout.c b/builtin/checkout.c\n> > index bfa5419f335..98f98256608 100644\n> > --- a/builtin/checkout.c\n> > +++ b/builtin/checkout.c\n> > @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n> >  \tif (!ce)\n> >  \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n> >  \tstatus = checkout_entry(ce, state, NULL);\n> > +\tfree(ce);\n> >  \treturn status;\n> >  }\n> \n> Thanks for spotting this one and fixing it.  \n> \n> In case anybody is wondering what the \"only to leak\" comment before\n> this part of the code is about (which by the way may need to be\n> updated, as the bulk of its reasoning still applies but at least we\n> are no longer leaking with this patch), back when this code was\n> written in 2008 or so it wasn't kosher to free cache_entry under\n> certain conditions, but it has been a long time since it became OK\n> to free any cache entries in later 2011---we should have done this a\n> long time ago.\n\nThanks for the background. The next iteration will change that comment,\ntoo (simply removing \"just to leak\" and rewrapping to 74 columns/line.\n\nCiao,\nDscho\n"},{"id":"318142","messageId":"alpine.DEB.2.20.1704281257340.3480@virtualbox","threadId":"45809","inReplyTo":"885f5dbc-b5d0-5113-d2ee-e9bac47c4271@kdbg.org","subject":"Re: [PATCH 18/26] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T10:58:48Z","receivedAt":"2017-04-28T10:59:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> > Reported by, you guessed it, Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  builtin/fast-export.c | 1 +\n> >  1 file changed, 1 insertion(+)\n> >\n> > diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n> > index e0220630d00..828d41c0c11 100644\n> > --- a/builtin/fast-export.c\n> > +++ b/builtin/fast-export.c\n> > @@ -765,6 +765,7 @@ static void handle_tag(const char *name, struct tag\n> > *tag)\n> >          (int)(tagger_end - tagger), tagger,\n> >          tagger == tagger_end ? \"\" : \"\\n\",\n> >          (int)message_size, (int)message_size, message ? message : \"\");\n> > +\tfree(buf);\n> >  }\n> >\n> >  static struct commit *get_commit(struct rev_cmdline_entry *e, char\n> >  *full_name)\n> >\n> \n> There is an early return in the function that is not covered by this patch.\n\nThanks!\n\n> Look for \"case DROP\".\n\nOr for \"return\" ;-)\n\nI briefly looked into simply releasing the memory earlier, but the tagger\nvariable used just before the inserted free(buf) actually points into the\nbuffer, so I had to repeat the free(buf) for the early return.\n\nThank you!\nDscho\n"},{"id":"318143","messageId":"alpine.DEB.2.20.1704281301530.3480@virtualbox","threadId":"45809","inReplyTo":"4ae94881-305f-380b-e786-c7f4ea5735e3@kdbg.org","subject":"Re: [PATCH 20/26] line-log: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T11:02:19Z","receivedAt":"2017-04-28T11:03:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> > Discovered by Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  line-log.c | 1 +\n> >  1 file changed, 1 insertion(+)\n> >\n> > diff --git a/line-log.c b/line-log.c\n> > index a23b910471b..19d46e9ea2c 100644\n> > --- a/line-log.c\n> > +++ b/line-log.c\n> > @@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct\n> > rev_info *rev, struct commit *c\n> >   changed = process_all_files(&parent_range, rev, &queue, range);\n> >   if (parent)\n> > \t\tadd_line_range(rev, parent, parent_range);\n> > +\tfree(parent_range);\n> >  \treturn changed;\n> >  }\n> >\n> >\n> \n> parent_range is of type struct line_log_data *, which needs more than a mere\n> free(). I think it's free_line_log_data(parent_range).\n\nOh wow, thanks for pointing that out. Will be fixed in the next iteration.\n\nCiao,\nDscho\n"},{"id":"318144","messageId":"20170428110827.7kiwidz7ks3o2d2o@sigill.intra.peff.net","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704281241260.3480@virtualbox","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-04-28T11:08:27Z","receivedAt":"2017-04-28T11:08:35Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 28, 2017 at 12:44:52PM +0200, Johannes Schindelin wrote:\n\n> > Also, what is the behavior of ungetc when we pass it EOF?\n> \n> According to the documentation, it would cast EOF to an unsigned char and\n> push that back. Definitely incorrect.\n> \n> > It looks like POSIX does what we want (pushing EOF is a noop, and the\n> > stream retains its feof() status), but I don't know if there are other\n> > implementations to worry about.\n> \n> That's not what my man page here says:\n> \n> \tungetc()  pushes  c  back to stream, cast to unsigned char, where\n> \tit is available for subsequent read operations.  Pushed-back\n> \tcharacters will be returned in reverse order; only one pushback is\n> \tguaranteed.\n\nPOSIX covers this this case explicitly:\n\n  If the value of c equals that of the macro EOF, the operation shall\n  fail and the input stream shall be left unchanged.\n\nThat comes straight from C99, which says:\n\n  If the value of c equals that of the macro EOF, the operation fails\n  and the input stream is unchanged.\n\nI don't have a copy of C89 handy, but I didn't see any mention of the\nbehavior in the \"changes from the previous edition\" section of C99.\n\nSo it's possible that there's an implementation that is unhappy with\nungetc(EOF), but unless we know of one specifically, it seems pretty\nsafe. Given that and the similar explicit rule for EOF via isspace(), I\nthink the original code actually behaves fine.\n\nOf course, we do not use the standard isspace() anyway. Our\nimplementation will cast the EOF to an unsigned char. If it's \"-1\", that\nends up as 255, which matches no classes. But if the platform has an\noddball EOF like 288, that would confuse our isspace().\n\n-Peff\n"},{"id":"318145","messageId":"20170428112002.tjkcjjdfqenl2aie@sigill.intra.peff.net","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704281206500.3480@virtualbox","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-04-28T11:20:02Z","receivedAt":"2017-04-28T11:20:59Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 28, 2017 at 12:41:02PM +0200, Johannes Schindelin wrote:\n\n> > Why? isspace(EOF) is well-defined.\n> \n> So let's look at the man page on Linux:\n> \n> \tThese functions check whether c,  which  must  have  the  value  of  an\n> \tunsigned char or EOF, [...]\n> \n> That is the only mention of it. I find it highly unobvious whether EOF\n> should be treated as a space or not. So let's look at the MSDN page\n> (https://msdn.microsoft.com/en-us/library/y13z34da.aspx) whether they talk\n> more about EOF:\n> \n> \tThe behavior of isspace and _isspace_l is undefined if c is not\n> \tEOF or in the range 0 through 0xFF, inclusive.\n> \n> That's it. So I kind of *guess* that EOF is treated as not being a\n> whitespace character (why does this make me think of politics now? Focus,\n> Johannes, focus...). But the mathematician in me protests: why would we\n> be able to decide the character class of a character that does not exist?\n\nThis behavior actually comes from the C standard. From C99, 7.4:\n\n  1 The header <ctype.h> declares several functions useful for\n    classifying and mapping characters. 166) In all cases the argument\n    is an int, the value of which shall be representable as an unsigned\n    char or shall equal the value of the macro EOF. If the argument has\n    any other value, the behavior is undefined.\n\nIt doesn't explicitly say that EOF returns false for these functions,\nbut it does seem implied. For instance:\n\n  The isspace function tests for any character that is a standard\n  white-space character or is one of a locale-specific set of characters\n  for which isalnum is false. The standard white-space characters are\n  the following: space (' '), form feed ('\\f'), new-line ('\\n'),\n  carriage return ('\\r'), horizontal tab ('\\t'), and vertical tab\n  ('\\v'). In the \"C\" locale, isspace returns true only for the standard\n  white-space characters.\n\nSo I think it is a reasonable thing to depend on.  But as I said\nelsewhere in the thread, we don't actually use the standard isspace()\nanyway.\n\n> But then, I guess I misunderstood what Coverity complained about: maybe\n> the problem was not so much the isspace() call but that EOF is not being\n> handled correctly. We pass it, unchecked, to ungetc().\n> \n> It appears that I (or Coverity, if you will), missed another instance\n> where we simply passed EOF unchecked to ungetc().\n\nI think that is also fine according to the standard.\n\nDo you happen to have the exact error from Coverity? I'm wondering if it\nis complaining about some aspect of our custom isspace() when used with\nEOF.\n\n> The next iteration will have it completely reworked: I no longer guard the\n> isspace() behind an `!= EOF` check, but rather handle an early EOF as I\n> think it should be handled. Extra eyes very welcome (this is the fixup!\n> patch):\n\nI do think handling EOF explicitly is probably a better strategy anyway,\nas it lets us tell when we have an empty patch.\n\n-Peff\n"},{"id":"318146","messageId":"alpine.DEB.2.20.1704281311500.3480@virtualbox","threadId":"45809","inReplyTo":"74da6153-2ce4-4224-d8d4-5be7481431ef@kdbg.org","subject":"Re: [PATCH 22/26] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T11:33:20Z","receivedAt":"2017-04-28T11:33:32Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:21 schrieb Johannes Schindelin:\n> > We free()d the `log` buffer when dwim_log() returned 1, but not when it\n> > returned a larger value (which meant that it still allocated the buffer\n> > but we simply ignored it).\n> >\n> > Identified by Coverity.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >  reflog-walk.c | 6 +++++-\n> >  1 file changed, 5 insertions(+), 1 deletion(-)\n> >\n> > diff --git a/reflog-walk.c b/reflog-walk.c\n> > index 99679f58255..ec66f2b16e6 100644\n> > --- a/reflog-walk.c\n> > +++ b/reflog-walk.c\n> > @@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n> >    if (!reflogs || reflogs->nr == 0) {\n> >     struct object_id oid;\n> >     char *b;\n> > -\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) ==\n> > 1) {\n> > +\t\t\tint ret = dwim_log(branch, strlen(branch),\n> > +\t\t\t\t\t   oid.hash, &b);\n> > +\t\t\tif (ret > 1)\n> > +\t\t\t\tfree(b);\n> > +\t\t\telse if (ret == 1) {\n> >      if (reflogs) {\n> >       free(reflogs->ref);\n> >       free(reflogs);\n> >\n> \n> Right after this hunk, there is another conditional that looks like it\n> forgets to free reflogs.\n\nThanks! Seems I got too hung up with the line to which Coverity pointed\nand failed to see the bigger picture.\n\nIt seems that there are plenty of leaks, even further down. For one, the\n`branch` variable is not released at the very end of the function! One\nmight think that read_complete_reflogs() takes custody of it, but no, it\nxstrdup()s the refname right at the beginning.\n\nSo there was a lot more memory leaking going on in that function...\n\nCiao,\nDscho\n"},{"id":"318147","messageId":"alpine.DEB.2.20.1704281334060.3480@virtualbox","threadId":"45809","inReplyTo":"966db3c1-a2e4-1309-e178-b885d2a1108f@kdbg.org","subject":"Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T11:36:59Z","receivedAt":"2017-04-28T11:37:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Hannes,\n\nOn Thu, 27 Apr 2017, Johannes Sixt wrote:\n\n> Am 26.04.2017 um 22:19 schrieb Johannes Schindelin:\n> > I recently registered the git-for-windows fork with Coverity to ensure\n> > that even the Windows-specific patches get some static analysis love.\n> >\n> > While at it, I squashed a couple of obvious issues in the part that is\n> > not Windows-specific.\n> \n> Thanks for the fish. I'd looked at the series and had a few comments.\n> \n> Hunting memory leaks is the way to insanity.\n\nI hear you. Loud and clear.\n\n> Never again am I going to help with this.\n\nAwww? And here I thought I had your attention... *sniffle*\n\n;-)\n\n> I prefer to rewrite this codebase to C++ and have leak-free code by\n> design.\n\nI had the pleasure of working with some software developers in 2004 who\nwere experts at introducing memory leaks into C++ code.\n\nThe same bunch of people later produced Java code that sorted a string\nlist in cubic time (carefully avoiding java.util.Collections.sort(), of\ncourse).\n\nFor every fool-proof system invented, somebody invents a better fool.\n\nCiao,\nDscho\n"},{"id":"318150","messageId":"alpine.DEB.2.20.1704281346480.3480@virtualbox","threadId":"45809","inReplyTo":"20170428112002.tjkcjjdfqenl2aie@sigill.intra.peff.net","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:33:41Z","receivedAt":"2017-04-28T13:36:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Peff,\n\nOn Fri, 28 Apr 2017, Jeff King wrote:\n\n> On Fri, Apr 28, 2017 at 12:41:02PM +0200, Johannes Schindelin wrote:\n> \n> > But then, I guess I misunderstood what Coverity complained about:\n> > maybe the problem was not so much the isspace() call but that EOF is\n> > not being handled correctly. We pass it, unchecked, to ungetc().\n> > \n> > It appears that I (or Coverity, if you will), missed another instance\n> > where we simply passed EOF unchecked to ungetc().\n> \n> I think that is also fine according to the standard.\n> \n> Do you happen to have the exact error from Coverity?\n\nWow, that was unnecessarily hard. It is a major hassle to get to any\nscan other than the latest one.\n\nBut I did it. Call me tenatious.\n\nThe report says this:\n\n233        do {\n   2. negative_return_fn: Function mingw_fgetc(f) returns a negative number.\n   3. var_assign: Assigning: signed variable peek = mingw_fgetc.\n234                peek = fgetc(f);\n   CID 1049734: Negative array index read (NEGATIVE_RETURNS)\n   4.  negative_returns: Using variable peek as an index to array sane_ctype.\n235        } while (isspace(peek));\n236        ungetc(peek, f);\n\nSo part of the thing is that we use mingw_fgetc() instead of fgetc().\nHowever, the return value is *still* the one from the \"real\" fgetc(), even\nif we intercept what appears to be a Ctrl+C from an interactive console.\n\n> I'm wondering if it is complaining about some aspect of our custom\n> isspace() when used with EOF.\n\nThat would appear to be the real issue, yes, and I should have\ndouble-checked the claim that POSIX isspace() handles EOF properly: we\noverride isspace() with our own version, after all:\n\n\t#define isspace(x) sane_istest(x,GIT_SPACE)\n\nwhere\n\n\t#define sane_istest(x,mask) \\\n\t\t((sane_ctype[(unsigned char)(x)] & (mask)) != 0)\n\n(rewrapped for readability)\n\nAs usual, EOF is defined as -1 in Git for Windows' context, meaning that\nwe look at the last entry of the sane_ctype array, which returns 0 for any\nsane_istest(x,mask) test for x >= 0x80:\n\n        /* Nothing in the 128.. range */\n\nSo it would appear that it happens to work, but I doubt that it was\nintentional.\n\nHaving said that, it is really curious why Coverity should get confused by\nthe code and not realize that casting a negative number to (unsigned char)\nwill make it valid as an index for the sane_ctype array.\n\nI double-checked, and there is no override for the isspace() function in\nwhat Coverity calls a \"model file\" (i.e. pseudo code intended to helping\nCoverity realize where it can stop reporting false positives).\n\n> > The next iteration will have it completely reworked: I no longer guard\n> > the isspace() behind an `!= EOF` check, but rather handle an early EOF\n> > as I think it should be handled. Extra eyes very welcome (this is the\n> > fixup!  patch):\n> \n> I do think handling EOF explicitly is probably a better strategy anyway,\n> as it lets us tell when we have an empty patch.\n\nI agree, I came to the same conclusion independently.\n\nCiao,\nDscho\n"},{"id":"318151","messageId":"alpine.DEB.2.20.1704281536160.3480@virtualbox","threadId":"45809","inReplyTo":"20170428110827.7kiwidz7ks3o2d2o@sigill.intra.peff.net","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:37:04Z","receivedAt":"2017-04-28T13:37:20Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Peff,\n\nOn Fri, 28 Apr 2017, Jeff King wrote:\n\n> On Fri, Apr 28, 2017 at 12:44:52PM +0200, Johannes Schindelin wrote:\n> \n> > > Also, what is the behavior of ungetc when we pass it EOF?\n> > \n> > According to the documentation, it would cast EOF to an unsigned char and\n> > push that back. Definitely incorrect.\n> > \n> > > It looks like POSIX does what we want (pushing EOF is a noop, and the\n> > > stream retains its feof() status), but I don't know if there are other\n> > > implementations to worry about.\n> > \n> > That's not what my man page here says:\n> > \n> > \tungetc()  pushes  c  back to stream, cast to unsigned char, where\n> > \tit is available for subsequent read operations.  Pushed-back\n> > \tcharacters will be returned in reverse order; only one pushback is\n> > \tguaranteed.\n> \n> POSIX covers this this case explicitly:\n> \n>   If the value of c equals that of the macro EOF, the operation shall\n>   fail and the input stream shall be left unchanged.\n> \n> That comes straight from C99, which says:\n> \n>   If the value of c equals that of the macro EOF, the operation fails\n>   and the input stream is unchanged.\n> \n> I don't have a copy of C89 handy, but I didn't see any mention of the\n> behavior in the \"changes from the previous edition\" section of C99.\n\nYeah. I'd still be more comfortable with being explicit in this case, also\nbecause our documentation states explicitly that we do not necessarily\nlive by the POSIX standard.\n\nCiao,\nDscho\n"},{"id":"318152","messageId":"alpine.DEB.2.20.1704281538140.3480@virtualbox","threadId":"45809","inReplyTo":"xmqq8tmmo0q6.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 06/26] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:39:07Z","receivedAt":"2017-04-28T13:39:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio & Stefan,\n\n\nOn Wed, 26 Apr 2017, Junio C Hamano wrote:\n\n> Stefan Beller <sbeller@google.com> writes:\n> \n> >> -       if (get_oid_hex(x, commit_id) < 0)\n> >> -               return -1;\n> >> +       if (!ret && get_oid_hex(x, commit_id) < 0)\n> >> +               ret = -1;\n> >>\n> >\n> > In similar cases of fixing mem leaks, we'd put a label here\n> > and make excessive use of goto, instead of setting ret to -1.\n> > As \"ret\" and the commands are short, this is visually just as appealing.\n> \n> I wouldn't call that visually appealing.  Fixing resource leaks is\n> good, and only because this function is short enough and the funny\n> way to skip over various operation need to last for just a few\n> instructions, it is tolerable.  If the function were shorter, then\n> we may have used\n> \n> \tif (!strbuf_getline_lf() &&\n> \t    skip_prefix() &&\n> \t    !get_oid_hex())\n> \t\tret = 0; /* happy */\n> \telse\n> \t\tret = -1;\n> \trelease resources here;\n>         return ret;\n\nI did almost what you suggested here, but I avoided the explicit ret = 0,\nas it is initialized that way.\n\n> and that would have been OK.  If longer, as you said, jumping to a\n> label at the end of function to release the acquired resource would\n> be a lot more maintainable way than either of the above alternatives\n> that are only usable for short functions.\n> \n> The patch as posted makes the function fail to return -1 when it\n> finds problems, by the way.  It needs to return \"ret\" not the\n> hardcoded \"0\" at the end.\n\nOops.\n\nCiao,\nDscho\n"},{"id":"318153","messageId":"20170428134500.dzww4qea75elww2m@sigill.intra.peff.net","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704281346480.3480@virtualbox","subject":"Re: [PATCH 10/26] Check for EOF while parsing mails","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-04-28T13:45:00Z","receivedAt":"2017-04-28T13:45:16Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Fri, Apr 28, 2017 at 03:33:41PM +0200, Johannes Schindelin wrote:\n\n> As usual, EOF is defined as -1 in Git for Windows' context, meaning that\n> we look at the last entry of the sane_ctype array, which returns 0 for any\n> sane_istest(x,mask) test for x >= 0x80:\n> \n>         /* Nothing in the 128.. range */\n> \n> So it would appear that it happens to work, but I doubt that it was\n> intentional.\n\nYeah, that was the same analysis I came to. Even though it works, it is\na potential portability problem if a platform defines EOF in a weird\nway. The \"right\" thing in such a case is probably checking explicitly\nfor EOF, but I'd hate to add an extra conditional to sane_istest(). It's\na fairly hot code path. So I'm fine with punting on that until we see\nevidence of such a system.\n\n> Having said that, it is really curious why Coverity should get confused by\n> the code and not realize that casting a negative number to (unsigned char)\n> will make it valid as an index for the sane_ctype array.\n\nYeah, that is the part that confuses me, too. It seems like an easy\ncase to get right.\n\nOh well. If you are tweaking it to handle EOF separately for other\nreasons, then the Coverity question goes away entirely.\n\n-Peff\n"},{"id":"318154","messageId":"cover.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493237937.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 00/25] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:49:21Z","receivedAt":"2017-04-28T13:49:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"I recently registered the git-for-windows fork with Coverity to ensure\nthat even the Windows-specific patches get some static analysis love.\n\nWhile at it, I squashed a couple of obvious issues in the part that is\nnot Windows-specific.\n\nNote: while this patch series squashes some of those issues, the\nremaining issues are not necessarily all false positives (e.g. Coverity\ngetting fooled by our FLEX_ARRAY trick into believing that the last\nmember of the struct is indeed a 0 or 1 size array) or intentional (e.g.\nbuiltins not releasing memory because exit() is called right after\nreturning from the function that leaks memory).\n\nNotable examples of the remaining issues are:\n\n- a couple of callers of shorten_unambiguous_ref() assume that they do\n  not have to release the memory returned from that function, often\n  assigning the pointer to a `const` variable that typically does not\n  hold a pointer that needs to be free()d. My hunch is that we will want\n  to convert that function to have a fixed number of static buffers and\n  use those in a round robin fashion à la sha1_to_hex().\n\n- pack-redundant.c seems to have hard-to-reason-about code paths that\n  may eventually leak memory. Essentially, the custody of the allocated\n  memory is not clear at all.\n\n- fast-import.c calls strbuf_detach() on the command_buf without any\n  obvious rationale. Turns out that *some* code paths assign\n  command_buf.buf to a `recent_command` which releases the buffer later.\n  However, from a cursory look it appears to me as if there are some\n  other code paths that skip that assignment, effectively causing a memory\n  leak once strbuf_detach() is called.\n\nSadly, I lack the time to pursue those remaining issues further.\n\nChanges since v1:\n\n- clarified in the commit messages for the setup_*git_dir() functions\n  that we are not really plugging a memory leak, but marking singletons\n  as `static` to help Coverity not to complain about this again\n\n- dropped the patch to http-backend, as it is supposedly a one-shot\n  program using exit() as \"garbage collector\".\n\n- the difftool patch does a more thorough job of fixing leaks now\n\n- reworded the commit subject of the mailinfo/mailsplit patch to sport\n  a prefix indicating the overall area of the fix\n\n- changed the mailinfo/mailsplit patch to *really* handle EOF correctly\n\n- simplified the patch to get_mail_commit_oid(), and now it even returns\n  the correct error value!\n\n- adjusted the comment in builtin/checkout.c that talked about leaking\n  the cache_entry (which is not leaked anymore)\n\n- add forgotten free(buf) in fast-export.c in an early return\n\n- line-log data is now released properly\n\n- a couple more memory leaks in add_reflog_for_walk() have been found\n  and addressed (this one *really* needs a couple more eyeballs, though,\n  it is just a much bigger change than I originally anticipated)\n\n\nJohannes Schindelin (25):\n  mingw: avoid memory leak when splitting PATH\n  winansi: avoid use of uninitialized value\n  winansi: avoid buffer overrun\n  add_commit_patch_id(): avoid allocating memory unnecessarily\n  git_config_rename_section_in_file(): avoid resource leak\n  get_mail_commit_oid(): avoid resource leak\n  difftool: address a couple of resource/memory leaks\n  status: close file descriptor after reading git-rebase-todo\n  mailinfo & mailsplit: check for EOF while parsing\n  cat-file: fix memory leak\n  checkout: fix memory leak\n  split_commit_in_progress(): fix memory leak\n  setup_bare_git_dir(): help static analysis\n  setup_discovered_git_dir(): help static analysis\n  pack-redundant: plug memory leak\n  mktree: plug memory leaks reported by Coverity\n  fast-export: avoid leaking memory in handle_tag()\n  receive-pack: plug memory leak in update()\n  line-log: avoid memory leak\n  shallow: avoid memory leak\n  add_reflog_for_walk: avoid memory leak\n  remote: plug memory leak in match_explicit()\n  name-rev: avoid leaking memory in the `deref` case\n  show_worktree(): plug memory leak\n  submodule_uses_worktrees(): plug memory leak\n\n builtin/am.c             | 15 ++++++---------\n builtin/cat-file.c       |  1 +\n builtin/checkout.c       | 17 +++++++++--------\n builtin/difftool.c       | 33 +++++++++++++++++++++++----------\n builtin/fast-export.c    |  2 ++\n builtin/mailsplit.c      |  3 ++-\n builtin/mktree.c         |  5 +++--\n builtin/name-rev.c       |  7 +++++--\n builtin/pack-redundant.c |  1 +\n builtin/receive-pack.c   |  4 +++-\n builtin/worktree.c       |  8 +++++---\n compat/mingw.c           |  4 +++-\n compat/winansi.c         |  7 +++++++\n config.c                 |  5 ++++-\n line-log.c               |  1 +\n mailinfo.c               | 15 +++++++++++----\n patch-ids.c              |  3 ++-\n reflog-walk.c            | 20 +++++++++++++++++---\n remote.c                 |  5 +++--\n setup.c                  | 11 ++++++++---\n shallow.c                |  8 ++++++--\n worktree.c               |  2 +-\n wt-status.c              |  8 +++++++-\n 23 files changed, 130 insertions(+), 55 deletions(-)\n\n\nbase-commit: 027a3b943b444a3e3a76f9a89803fc10245b858f\nPublished-As: https://github.com/dscho/git/releases/tag/coverity-v2\nFetch-It-Via: git fetch https://github.com/dscho/git coverity-v2\n\nInterdiff vs v1:\n\n diff --git a/builtin/am.c b/builtin/am.c\n index 067dd4fc20d..9c5c2c778e2 100644\n --- a/builtin/am.c\n +++ b/builtin/am.c\n @@ -1353,18 +1353,14 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n  \tconst char *x;\n  \tint ret = 0;\n  \n -\tif (strbuf_getline_lf(&sb, fp))\n -\t\tret = -1;\n -\n -\tif (!ret && !skip_prefix(sb.buf, \"From \", &x))\n -\t\tret = -1;\n -\n -\tif (!ret && get_oid_hex(x, commit_id) < 0)\n +\tif (strbuf_getline_lf(&sb, fp) ||\n +\t    !skip_prefix(sb.buf, \"From \", &x) ||\n +\t    get_oid_hex(x, commit_id) < 0)\n  \t\tret = -1;\n  \n  \tstrbuf_release(&sb);\n  \tfclose(fp);\n -\treturn 0;\n +\treturn ret;\n  }\n  \n  /**\n diff --git a/builtin/checkout.c b/builtin/checkout.c\n index 98f98256608..5faea3a05fa 100644\n --- a/builtin/checkout.c\n +++ b/builtin/checkout.c\n @@ -235,14 +235,14 @@ static int checkout_merged(int pos, const struct checkout *state)\n  \t/*\n  \t * NEEDSWORK:\n  \t * There is absolutely no reason to write this as a blob object\n -\t * and create a phony cache entry just to leak.  This hack is\n -\t * primarily to get to the write_entry() machinery that massages\n -\t * the contents to work-tree format and writes out which only\n -\t * allows it for a cache entry.  The code in write_entry() needs\n -\t * to be refactored to allow us to feed a <buffer, size, mode>\n -\t * instead of a cache entry.  Such a refactoring would help\n -\t * merge_recursive as well (it also writes the merge result to the\n -\t * object database even when it may contain conflicts).\n +\t * and create a phony cache entry.  This hack is primarily to get\n +\t * to the write_entry() machinery that massages the contents to\n +\t * work-tree format and writes out which only allows it for a\n +\t * cache entry.  The code in write_entry() needs to be refactored\n +\t * to allow us to feed a <buffer, size, mode> instead of a cache\n +\t * entry.  Such a refactoring would help merge_recursive as well\n +\t * (it also writes the merge result to the object database even\n +\t * when it may contain conflicts).\n  \t */\n  \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n  \t\t\t    blob_type, oid.hash))\n diff --git a/builtin/difftool.c b/builtin/difftool.c\n index a4f1d117ef6..b9a892f2693 100644\n --- a/builtin/difftool.c\n +++ b/builtin/difftool.c\n @@ -440,8 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n  \t\t}\n  \n  \t\tif (lmode && status != 'C') {\n -\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate))\n -\t\t\t\treturn error(\"could not write '%s'\", src_path);\n +\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate)) {\n +\t\t\t\tret = error(\"could not write '%s'\", src_path);\n +\t\t\t\tgoto finish;\n +\t\t\t}\n  \t\t}\n  \n  \t\tif (rmode && !S_ISLNK(rmode)) {\n @@ -457,9 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n  \t\t\thashmap_add(&working_tree_dups, entry);\n  \n  \t\t\tif (!use_wt_file(workdir, dst_path, &roid)) {\n -\t\t\t\tif (checkout_path(rmode, &roid, dst_path, &rstate))\n -\t\t\t\t\treturn error(\"could not write '%s'\",\n -\t\t\t\t\t\t     dst_path);\n +\t\t\t\tif (checkout_path(rmode, &roid, dst_path,\n +\t\t\t\t\t\t  &rstate)) {\n +\t\t\t\t\tret = error(\"could not write '%s'\",\n +\t\t\t\t\t\t    dst_path);\n +\t\t\t\t\tgoto finish;\n +\t\t\t\t}\n  \t\t\t} else if (!is_null_oid(&roid)) {\n  \t\t\t\t/*\n  \t\t\t\t * Changes in the working tree need special\n @@ -474,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n  \t\t\t\t\t\tADD_CACHE_JUST_APPEND);\n  \n  \t\t\t\tadd_path(&rdir, rdir_len, dst_path);\n -\t\t\t\tif (ensure_leading_directories(rdir.buf))\n -\t\t\t\t\treturn error(\"could not create \"\n -\t\t\t\t\t\t     \"directory for '%s'\",\n -\t\t\t\t\t\t     dst_path);\n +\t\t\t\tif (ensure_leading_directories(rdir.buf)) {\n +\t\t\t\t\tret = error(\"could not create \"\n +\t\t\t\t\t\t    \"directory for '%s'\",\n +\t\t\t\t\t\t    dst_path);\n +\t\t\t\t\tgoto finish;\n +\t\t\t\t}\n  \t\t\t\tadd_path(&wtdir, wtdir_len, dst_path);\n  \t\t\t\tif (symlinks) {\n  \t\t\t\t\tif (symlink(wtdir.buf, rdir.buf)) {\n @@ -499,13 +506,14 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n  \t}\n  \n  \tfclose(fp);\n +\tfp = NULL;\n  \tif (finish_command(&child)) {\n  \t\tret = error(\"error occurred running diff --raw\");\n  \t\tgoto finish;\n  \t}\n  \n  \tif (!i)\n -\t\treturn 0;\n +\t\tgoto finish;\n  \n  \t/*\n  \t * Changes to submodules require special treatment.This loop writes a\n @@ -628,6 +636,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n  \t\texit_cleanup(tmpdir, rc);\n  \n  finish:\n +\tif (fp)\n +\t\tfclose(fp);\n +\n  \tfree(lbase_dir);\n  \tfree(rbase_dir);\n  \tstrbuf_release(&ldir);\n diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n index 828d41c0c11..64617ad8e36 100644\n --- a/builtin/fast-export.c\n +++ b/builtin/fast-export.c\n @@ -734,6 +734,7 @@ static void handle_tag(const char *name, struct tag *tag)\n  \t\t\t     oid_to_hex(&tag->object.oid));\n  \t\tcase DROP:\n  \t\t\t/* Ignore this tag altogether */\n +\t\t\tfree(buf);\n  \t\t\treturn;\n  \t\tcase REWRITE:\n  \t\t\tif (tagged->type != OBJ_COMMIT) {\n diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n index c0d88f97512..9b3efc8e987 100644\n --- a/builtin/mailsplit.c\n +++ b/builtin/mailsplit.c\n @@ -232,8 +232,9 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n  \n  \tdo {\n  \t\tpeek = fgetc(f);\n -\t} while (peek >= 0 && isspace(peek));\n -\tungetc(peek, f);\n +\t} while (isspace(peek));\n +\tif (peek != EOF)\n +\t\tungetc(peek, f);\n  \n  \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n  \t\t/* empty stdin is OK */\n diff --git a/http-backend.c b/http-backend.c\n index d12572fda10..eef0a361f4f 100644\n --- a/http-backend.c\n +++ b/http-backend.c\n @@ -681,10 +681,8 @@ int cmd_main(int argc, const char **argv)\n  \t\tif (!regexec(&re, dir, 1, out, 0)) {\n  \t\t\tsize_t n;\n  \n -\t\t\tif (strcmp(method, c->method)) {\n -\t\t\t\tfree(dir);\n +\t\t\tif (strcmp(method, c->method))\n  \t\t\t\treturn bad_request(&hdr, c);\n -\t\t\t}\n  \n  \t\t\tcmd = c;\n  \t\t\tn = out[0].rm_eo - out[0].rm_so;\n @@ -710,7 +708,5 @@ int cmd_main(int argc, const char **argv)\n  \t\t\t\t\t   max_request_buffer);\n  \n  \tcmd->imp(&hdr, cmd_arg);\n -\tfree(dir);\n -\tfree(cmd_arg);\n  \treturn 0;\n  }\n diff --git a/line-log.c b/line-log.c\n index 19d46e9ea2c..b9087814b8c 100644\n --- a/line-log.c\n +++ b/line-log.c\n @@ -1125,7 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n  \tchanged = process_all_files(&parent_range, rev, &queue, range);\n  \tif (parent)\n  \t\tadd_line_range(rev, parent, parent_range);\n -\tfree(parent_range);\n +\tfree_line_log_data(parent_range);\n  \treturn changed;\n  }\n  \n diff --git a/mailinfo.c b/mailinfo.c\n index 60dcad7b714..a319911b510 100644\n --- a/mailinfo.c\n +++ b/mailinfo.c\n @@ -882,7 +882,10 @@ static int read_one_header_line(struct strbuf *line, FILE *in)\n  \tfor (;;) {\n  \t\tint peek;\n  \n -\t\tpeek = fgetc(in); ungetc(peek, in);\n +\t\tpeek = fgetc(in);\n +\t\tif (peek == EOF)\n +\t\t\tbreak;\n +\t\tungetc(peek, in);\n  \t\tif (peek != ' ' && peek != '\\t')\n  \t\t\tbreak;\n  \t\tif (strbuf_getline_lf(&continuation, in))\n @@ -1094,14 +1097,18 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n  \t\treturn -1;\n  \t}\n  \n -\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n -\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n -\n  \tdo {\n  \t\tpeek = fgetc(mi->input);\n -\t} while (peek >= 0 && isspace(peek));\n +\t\tif (peek == EOF) {\n +\t\t\tfclose(cmitmsg);\n +\t\t\treturn error(\"empty patch: '%s'\", patch);\n +\t\t}\n +\t} while (isspace(peek));\n  \tungetc(peek, mi->input);\n  \n +\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n +\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n +\n  \t/* process the email header */\n  \twhile (read_one_header_line(&line, mi->input))\n  \t\tcheck_header(mi, &line, mi->p_hdr_data, 1);\n diff --git a/reflog-walk.c b/reflog-walk.c\n index ec66f2b16e6..c63eb1a3fd7 100644\n --- a/reflog-walk.c\n +++ b/reflog-walk.c\n @@ -197,17 +197,27 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n  \t\t\t\treflogs = read_complete_reflog(branch);\n  \t\t\t}\n  \t\t}\n -\t\tif (!reflogs || reflogs->nr == 0)\n +\t\tif (!reflogs || reflogs->nr == 0) {\n +\t\t\tif (reflogs) {\n +\t\t\t\tfree(reflogs->ref);\n +\t\t\t\tfree(reflogs);\n +\t\t\t}\n +\t\t\tfree(branch);\n  \t\t\treturn -1;\n +\t\t}\n  \t\tstring_list_insert(&info->complete_reflogs, branch)->util\n  \t\t\t= reflogs;\n  \t}\n +\tfree(branch);\n  \n  \tcommit_reflog = xcalloc(1, sizeof(struct commit_reflog));\n  \tif (recno < 0) {\n  \t\tcommit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);\n  \t\tif (commit_reflog->recno < 0) {\n -\t\t\tfree(branch);\n +\t\t\tif (reflogs) {\n +\t\t\t\tfree(reflogs->ref);\n +\t\t\t\tfree(reflogs);\n +\t\t\t}\n  \t\t\tfree(commit_reflog);\n  \t\t\treturn -1;\n  \t\t}\n\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318155","messageId":"0359bddb6fe5fd74ce2571f9933c18dfeb2a8f7e.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 01/25] mingw: avoid memory leak when splitting PATH","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:49:27Z","receivedAt":"2017-04-28T13:49:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In the (admittedly, concocted) case that PATH consists only of colons, we\nwould leak the duplicated string.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 3fbfda5978b..fe0e3ccd248 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -961,8 +961,10 @@ static char **get_path_split(void)\n \t\t\t++n;\n \t\t}\n \t}\n-\tif (!n)\n+\tif (!n) {\n+\t\tfree(envpath);\n \t\treturn NULL;\n+\t}\n \n \tALLOC_ARRAY(path, n + 1);\n \tp = envpath;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318156","messageId":"6e471ec11ad13b5d3256d2c579ffad6fc3491d3b.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 02/25] winansi: avoid use of uninitialized value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:49:31Z","receivedAt":"2017-04-28T13:49:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When stdout is not connected to a Win32 console, we incorrectly used an\nuninitialized value for the \"plain\" character attributes.\n\nDetected by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex 793420f9d0d..fd6910746c8 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -105,6 +105,8 @@ static int is_console(int fd)\n \tif (!fd) {\n \t\tif (!GetConsoleMode(hcon, &mode))\n \t\t\treturn 0;\n+\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n+\t\t\tFOREGROUND_RED;\n \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n \t\treturn 0;\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318157","messageId":"56849b5d1edefb55d5c648d2930d07fe73244bfa.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 03/25] winansi: avoid buffer overrun","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:49:49Z","receivedAt":"2017-04-28T13:50:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we could not convert the UTF-8 sequence into Unicode for writing to\nthe Console, we should not try to write an insanely-long sequence of\ninvalid wide characters (mistaking the negative return value for an\nunsigned length).\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex fd6910746c8..861b79d8c31 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -135,6 +135,11 @@ static void write_console(unsigned char *str, size_t len)\n \n \t/* convert utf-8 to utf-16 */\n \tint wlen = xutftowcsn(wbuf, (char*) str, ARRAY_SIZE(wbuf), len);\n+\tif (wlen < 0) {\n+\t\twchar_t *err = L\"[invalid]\";\n+\t\tWriteConsoleW(console, err, wcslen(err), &dummy, NULL);\n+\t\treturn;\n+\t}\n \n \t/* write directly to console */\n \tWriteConsoleW(console, wbuf, wlen, &dummy, NULL);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318158","messageId":"21697d727ff5aa3b8b70360a978c295415995744.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 04/25] add_commit_patch_id(): avoid allocating memory unnecessarily","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:50:09Z","receivedAt":"2017-04-28T13:50:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"It would appear that we allocate (and forget to release) memory if the\npatch ID is not even defined.\n\nReported by the Coverity tool.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n patch-ids.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/patch-ids.c b/patch-ids.c\nindex fa8f11de826..92eba7a059e 100644\n--- a/patch-ids.c\n+++ b/patch-ids.c\n@@ -99,11 +99,12 @@ struct patch_id *has_commit_patch_id(struct commit *commit,\n struct patch_id *add_commit_patch_id(struct commit *commit,\n \t\t\t\t     struct patch_ids *ids)\n {\n-\tstruct patch_id *key = xcalloc(1, sizeof(*key));\n+\tstruct patch_id *key;\n \n \tif (!patch_id_defined(commit))\n \t\treturn NULL;\n \n+\tkey = xcalloc(1, sizeof(*key));\n \tif (init_patch_id_entry(key, commit, ids)) {\n \t\tfree(key);\n \t\treturn NULL;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318159","messageId":"aed88de3501817b6d3586a1a27cbd2006b1407cf.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 05/25] git_config_rename_section_in_file(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:50:18Z","receivedAt":"2017-04-28T13:50:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In case of errors, we really want the file descriptor to be closed.\n\nDiscovered by a Coverity scan.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.c | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/config.c b/config.c\nindex b4a3205da32..a30056ec7e9 100644\n--- a/config.c\n+++ b/config.c\n@@ -2621,7 +2621,7 @@ int git_config_rename_section_in_file(const char *config_filename,\n \tstruct lock_file *lock;\n \tint out_fd;\n \tchar buf[1024];\n-\tFILE *config_file;\n+\tFILE *config_file = NULL;\n \tstruct stat st;\n \n \tif (new_name && !section_name_is_ok(new_name)) {\n@@ -2703,11 +2703,14 @@ int git_config_rename_section_in_file(const char *config_filename,\n \t\t}\n \t}\n \tfclose(config_file);\n+\tconfig_file = NULL;\n commit_and_out:\n \tif (commit_lock_file(lock) < 0)\n \t\tret = error_errno(\"could not write config file %s\",\n \t\t\t\t  config_filename);\n out:\n+\tif (config_file)\n+\t\tfclose(config_file);\n \trollback_lock_file(lock);\n out_no_rollback:\n \tfree(filename_buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318160","messageId":"254784d80407e0eb138f52ec5f9724fcbcda92c5.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 07/25] difftool: address a couple of resource/memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:50:25Z","receivedAt":"2017-04-28T13:50:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change plugs a couple of memory leaks and makes sure that the file\ndescriptor is closed in run_dir_diff().\n\nSpotted by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/difftool.c | 33 +++++++++++++++++++++++----------\n 1 file changed, 23 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex 1354d0e4625..b9a892f2693 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,\n \t\thashmap_entry_init(entry, strhash(buf.buf));\n \t\thashmap_add(result, entry);\n \t}\n+\tfclose(fp);\n \tif (finish_command(&diff_files))\n \t\tdie(\"diff-files did not exit properly\");\n \tstrbuf_release(&index_env);\n@@ -439,8 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \n \t\tif (lmode && status != 'C') {\n-\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate))\n-\t\t\t\treturn error(\"could not write '%s'\", src_path);\n+\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate)) {\n+\t\t\t\tret = error(\"could not write '%s'\", src_path);\n+\t\t\t\tgoto finish;\n+\t\t\t}\n \t\t}\n \n \t\tif (rmode && !S_ISLNK(rmode)) {\n@@ -456,9 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\thashmap_add(&working_tree_dups, entry);\n \n \t\t\tif (!use_wt_file(workdir, dst_path, &roid)) {\n-\t\t\t\tif (checkout_path(rmode, &roid, dst_path, &rstate))\n-\t\t\t\t\treturn error(\"could not write '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (checkout_path(rmode, &roid, dst_path,\n+\t\t\t\t\t\t  &rstate)) {\n+\t\t\t\t\tret = error(\"could not write '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t} else if (!is_null_oid(&roid)) {\n \t\t\t\t/*\n \t\t\t\t * Changes in the working tree need special\n@@ -473,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\t\t\t\tADD_CACHE_JUST_APPEND);\n \n \t\t\t\tadd_path(&rdir, rdir_len, dst_path);\n-\t\t\t\tif (ensure_leading_directories(rdir.buf))\n-\t\t\t\t\treturn error(\"could not create \"\n-\t\t\t\t\t\t     \"directory for '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (ensure_leading_directories(rdir.buf)) {\n+\t\t\t\t\tret = error(\"could not create \"\n+\t\t\t\t\t\t    \"directory for '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t\tadd_path(&wtdir, wtdir_len, dst_path);\n \t\t\t\tif (symlinks) {\n \t\t\t\t\tif (symlink(wtdir.buf, rdir.buf)) {\n@@ -497,13 +505,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \t}\n \n+\tfclose(fp);\n+\tfp = NULL;\n \tif (finish_command(&child)) {\n \t\tret = error(\"error occurred running diff --raw\");\n \t\tgoto finish;\n \t}\n \n \tif (!i)\n-\t\treturn 0;\n+\t\tgoto finish;\n \n \t/*\n \t * Changes to submodules require special treatment.This loop writes a\n@@ -626,6 +636,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\texit_cleanup(tmpdir, rc);\n \n finish:\n+\tif (fp)\n+\t\tfclose(fp);\n+\n \tfree(lbase_dir);\n \tfree(rbase_dir);\n \tstrbuf_release(&ldir);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318161","messageId":"498595a4ef9d56c0b42fcd0d8815a6fea598f9dd.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 06/25] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:50:22Z","receivedAt":"2017-04-28T13:50:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we fail to read, or parse, the file, we still want to close the file\ndescriptor and release the strbuf.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/am.c | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex a95dd8b4e6c..9c5c2c778e2 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1351,19 +1351,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *fp = xfopen(mail, \"r\");\n \tconst char *x;\n+\tint ret = 0;\n \n-\tif (strbuf_getline_lf(&sb, fp))\n-\t\treturn -1;\n-\n-\tif (!skip_prefix(sb.buf, \"From \", &x))\n-\t\treturn -1;\n-\n-\tif (get_oid_hex(x, commit_id) < 0)\n-\t\treturn -1;\n+\tif (strbuf_getline_lf(&sb, fp) ||\n+\t    !skip_prefix(sb.buf, \"From \", &x) ||\n+\t    get_oid_hex(x, commit_id) < 0)\n+\t\tret = -1;\n \n \tstrbuf_release(&sb);\n \tfclose(fp);\n-\treturn 0;\n+\treturn ret;\n }\n \n /**\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318162","messageId":"d399458fd03d15445d5e537ca042789652386e2a.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 08/25] status: close file descriptor after reading git-rebase-todo","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T13:50:29Z","receivedAt":"2017-04-28T13:51:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 03754849626..0a6e16dbe0f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1168,6 +1168,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)\n \t\tabbrev_sha1_in_line(&line);\n \t\tstring_list_append(lines, line.buf);\n \t}\n+\tfclose(f);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318163","messageId":"32a2d16902734c8794de61b5e86a0d2a6cf43fa3.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 09/25] mailinfo & mailsplit: check for EOF while parsing","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:02:57Z","receivedAt":"2017-04-28T14:03:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"While POSIX states that it is okay to pass EOF to isspace() (and it seems\nto be implied that EOF should *not* be treated as whitespace), and also to\npass EOF to ungetc() (which seems to be intended to fail without buffering\nthe character), it is much better to handle these cases explicitly. Not\nonly does it reduce head-scratching (and helps static analysis avoid\nreporting false positives), it also lets us handle files containing\nnothing but whitespace by erroring out.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mailsplit.c |  3 ++-\n mailinfo.c          | 15 +++++++++++----\n 2 files changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\nindex 30681681c13..9b3efc8e987 100644\n--- a/builtin/mailsplit.c\n+++ b/builtin/mailsplit.c\n@@ -233,7 +233,8 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n \tdo {\n \t\tpeek = fgetc(f);\n \t} while (isspace(peek));\n-\tungetc(peek, f);\n+\tif (peek != EOF)\n+\t\tungetc(peek, f);\n \n \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n \t\t/* empty stdin is OK */\ndiff --git a/mailinfo.c b/mailinfo.c\nindex 68037758f2f..a319911b510 100644\n--- a/mailinfo.c\n+++ b/mailinfo.c\n@@ -882,7 +882,10 @@ static int read_one_header_line(struct strbuf *line, FILE *in)\n \tfor (;;) {\n \t\tint peek;\n \n-\t\tpeek = fgetc(in); ungetc(peek, in);\n+\t\tpeek = fgetc(in);\n+\t\tif (peek == EOF)\n+\t\t\tbreak;\n+\t\tungetc(peek, in);\n \t\tif (peek != ' ' && peek != '\\t')\n \t\t\tbreak;\n \t\tif (strbuf_getline_lf(&continuation, in))\n@@ -1094,14 +1097,18 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n \t\treturn -1;\n \t}\n \n-\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n-\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n-\n \tdo {\n \t\tpeek = fgetc(mi->input);\n+\t\tif (peek == EOF) {\n+\t\t\tfclose(cmitmsg);\n+\t\t\treturn error(\"empty patch: '%s'\", patch);\n+\t\t}\n \t} while (isspace(peek));\n \tungetc(peek, mi->input);\n \n+\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n+\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n+\n \t/* process the email header */\n \twhile (read_one_header_line(&line, mi->input))\n \t\tcheck_header(mi, &line, mi->p_hdr_data, 1);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318164","messageId":"633670d87f7080d1e21f1f639bc560499572f3f7.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 10/25] cat-file: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:01Z","receivedAt":"2017-04-28T14:03:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/cat-file.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 1890d7a6390..9af863e7915 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \t\tdie(\"git cat-file %s: bad file\", obj_name);\n \n \twrite_or_die(1, buf, size);\n+\tfree(buf);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318165","messageId":"7743bfd9e0cde54db7161007ea2208016d18bad3.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 11/25] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:05Z","receivedAt":"2017-04-28T14:03:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change addresses part of the NEEDSWORK comment above the code,\ntherefore the comment needs to be adjusted, too.\n\nDiscovered via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/checkout.c | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex bfa5419f335..5faea3a05fa 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -235,14 +235,14 @@ static int checkout_merged(int pos, const struct checkout *state)\n \t/*\n \t * NEEDSWORK:\n \t * There is absolutely no reason to write this as a blob object\n-\t * and create a phony cache entry just to leak.  This hack is\n-\t * primarily to get to the write_entry() machinery that massages\n-\t * the contents to work-tree format and writes out which only\n-\t * allows it for a cache entry.  The code in write_entry() needs\n-\t * to be refactored to allow us to feed a <buffer, size, mode>\n-\t * instead of a cache entry.  Such a refactoring would help\n-\t * merge_recursive as well (it also writes the merge result to the\n-\t * object database even when it may contain conflicts).\n+\t * and create a phony cache entry.  This hack is primarily to get\n+\t * to the write_entry() machinery that massages the contents to\n+\t * work-tree format and writes out which only allows it for a\n+\t * cache entry.  The code in write_entry() needs to be refactored\n+\t * to allow us to feed a <buffer, size, mode> instead of a cache\n+\t * entry.  Such a refactoring would help merge_recursive as well\n+\t * (it also writes the merge result to the object database even\n+\t * when it may contain conflicts).\n \t */\n \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n \t\t\t    blob_type, oid.hash))\n@@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n \tif (!ce)\n \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n \tstatus = checkout_entry(ce, state, NULL);\n+\tfree(ce);\n \treturn status;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318166","messageId":"da7222c92aed4dc470965df7319411f1098e04e6.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 12/25] split_commit_in_progress(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:08Z","receivedAt":"2017-04-28T14:03:29Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 0a6e16dbe0f..1f3f6bcb980 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status *s)\n \tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n \n \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n-\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n+\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n+\t\tfree(head);\n+\t\tfree(orig_head);\n+\t\tfree(rebase_amend);\n+\t\tfree(rebase_orig_head);\n \t\treturn split_in_progress;\n+\t}\n \n \tif (!strcmp(rebase_amend, rebase_orig_head)) {\n \t\tif (strcmp(head, rebase_amend))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318167","messageId":"e19e2bb59f9a81a59669385d5c69674808af8469.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 13/25] setup_bare_git_dir(): help static analysis","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:18Z","receivedAt":"2017-04-28T14:03:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Coverity reported a memory leak in this function. However, it can only\nbe called once, as setup_git_directory() changes global state and hence\nis not reentrant.\n\nMark the variable as static to indicate that this is a singleton.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0309c278218..0320a9ad14c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n-\t\tconst char *gitdir;\n+\t\tstatic const char *gitdir;\n \n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318168","messageId":"cbd8e917f1318190d9f979f4cc9b62dcd838bbb0.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 14/25] setup_discovered_git_dir(): help static analysis","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:22Z","receivedAt":"2017-04-28T14:03:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Coverity reported a memory leak in this function. However, it can only\nbe called once, as setup_git_directory() changes global state and hence\nis not reentrant.\n\nMark the variable as static to indicate that this is a singleton.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0320a9ad14c..12efca85a41 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n+\t\tchar *p = NULL;\n+\t\tconst char *ret;\n+\n \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n-\t\t\tgitdir = real_pathdup(gitdir, 1);\n+\t\t\tgitdir = p = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(\"Could not come back to cwd\");\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tfree(p);\n+\t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318169","messageId":"7f627e2d67c165fcd2e3ef8642df468efd69224c.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 15/25] pack-redundant: plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:25Z","receivedAt":"2017-04-28T14:03:39Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Identified via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/pack-redundant.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 72c815844dd..cb1df1c7614 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -442,6 +442,7 @@ static void minimize(struct pack_list **min)\n \t/* return if there are no objects missing from the unique set */\n \tif (missing->size == 0) {\n \t\t*min = unique;\n+\t\tfree(missing);\n \t\treturn;\n \t}\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318170","messageId":"32f1cb4d925ff7a80b9a58983e0bcebf7ccff9cb.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 16/25] mktree: plug memory leaks reported by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:30Z","receivedAt":"2017-04-28T14:03:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mktree.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/mktree.c b/builtin/mktree.c\nindex de9b40fc63b..f0354bc9718 100644\n--- a/builtin/mktree.c\n+++ b/builtin/mktree.c\n@@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \tunsigned mode;\n \tenum object_type mode_type; /* object type derived from mode */\n \tenum object_type obj_type; /* object type derived from sha */\n-\tchar *path;\n+\tchar *path, *p = NULL;\n \tunsigned char sha1[20];\n \n \tptr = buf;\n@@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t\tstruct strbuf p_uq = STRBUF_INIT;\n \t\tif (unquote_c_style(&p_uq, path, NULL))\n \t\t\tdie(\"invalid quoting\");\n-\t\tpath = strbuf_detach(&p_uq, NULL);\n+\t\tpath = p = strbuf_detach(&p_uq, NULL);\n \t}\n \n \t/*\n@@ -136,6 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t}\n \n \tappend_to_tree(mode, sha1, path);\n+\tfree(p);\n }\n \n int cmd_mktree(int ac, const char **av, const char *prefix)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318171","messageId":"7a701d8239b4413e8733bcde938e2da186b87881.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 17/25] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:33Z","receivedAt":"2017-04-28T14:03:55Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by, you guessed it, Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/fast-export.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex e0220630d00..64617ad8e36 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -734,6 +734,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t\t\t     oid_to_hex(&tag->object.oid));\n \t\tcase DROP:\n \t\t\t/* Ignore this tag altogether */\n+\t\t\tfree(buf);\n \t\t\treturn;\n \t\tcase REWRITE:\n \t\t\tif (tagged->type != OBJ_COMMIT) {\n@@ -765,6 +766,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t       (int)(tagger_end - tagger), tagger,\n \t       tagger == tagger_end ? \"\" : \"\\n\",\n \t       (int)message_size, (int)message_size, message ? message : \"\");\n+\tfree(buf);\n }\n \n static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318172","messageId":"fabb32a7e994e8053b0ac08a5efa2868509c03d6.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 18/25] receive-pack: plug memory leak in update()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:03:36Z","receivedAt":"2017-04-28T14:04:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/receive-pack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f96834f42c9..48c07ddb659 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -986,7 +986,8 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstatic char *namespaced_name;\n+\tconst char *ret;\n \tstruct object_id *old_oid = &cmd->old_oid;\n \tstruct object_id *new_oid = &cmd->new_oid;\n \n@@ -997,6 +998,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t}\n \n \tstrbuf_addf(&namespaced_name_buf, \"%s%s\", get_git_namespace(), name);\n+\tfree(namespaced_name);\n \tnamespaced_name = strbuf_detach(&namespaced_name_buf, NULL);\n \n \tif (is_ref_checked_out(namespaced_name)) {\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318173","messageId":"6b0eda48e005b373cf573a9f58d9a084336f9b27.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 19/25] line-log: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:12Z","receivedAt":"2017-04-28T14:04:25Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n line-log.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/line-log.c b/line-log.c\nindex a23b910471b..b9087814b8c 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n \tchanged = process_all_files(&parent_range, rev, &queue, range);\n \tif (parent)\n \t\tadd_line_range(rev, parent, parent_range);\n+\tfree_line_log_data(parent_range);\n \treturn changed;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318174","messageId":"380b55f118efb1b0eaa142e1d3971bca7d1ef17a.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 20/25] shallow: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:15Z","receivedAt":"2017-04-28T14:04:32Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n shallow.c | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/shallow.c b/shallow.c\nindex 25b6db989bf..f9370961f99 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -473,11 +473,15 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1,\n \tstruct commit_list *head = NULL;\n \tint bitmap_nr = (info->nr_bits + 31) / 32;\n \tsize_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);\n-\tuint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */\n-\tuint32_t *bitmap = paint_alloc(info);\n \tstruct commit *c = lookup_commit_reference_gently(sha1, 1);\n+\tuint32_t *tmp; /* to be freed before return */\n+\tuint32_t *bitmap;\n+\n \tif (!c)\n \t\treturn;\n+\n+\ttmp = xmalloc(bitmap_size);\n+\tbitmap = paint_alloc(info);\n \tmemset(bitmap, 0, bitmap_size);\n \tbitmap[id / 32] |= (1U << (id % 32));\n \tcommit_list_insert(c, &head);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318175","messageId":"235cd51a6a89141ab245ac8ee04d2c90ddfc9984.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 22/25] remote: plug memory leak in match_explicit()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:36Z","receivedAt":"2017-04-28T14:04:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The `guess_ref()` returns an allocated buffer of which `make_linked_ref()`\ndoes not take custody (`alloc_ref()` makes a copy), therefore we need to\nrelease the buffer afterwards.\n\nNoticed via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n remote.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 801137c72eb..72b4591b983 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1191,9 +1191,10 @@ static int match_explicit(struct ref *src, struct ref *dst,\n \t\telse if (is_null_oid(&matched_src->new_oid))\n \t\t\terror(\"unable to delete '%s': remote ref does not exist\",\n \t\t\t      dst_value);\n-\t\telse if ((dst_guess = guess_ref(dst_value, matched_src)))\n+\t\telse if ((dst_guess = guess_ref(dst_value, matched_src))) {\n \t\t\tmatched_dst = make_linked_ref(dst_guess, dst_tail);\n-\t\telse\n+\t\t\tfree(dst_guess);\n+\t\t} else\n \t\t\terror(\"unable to push to unqualified destination: %s\\n\"\n \t\t\t      \"The destination refspec neither matches an \"\n \t\t\t      \"existing ref on the remote nor\\n\"\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318176","messageId":"9e897d6f263bcf9a2b2bab613946fe1bf452eb91.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:39Z","receivedAt":"2017-04-28T14:04:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When the `name_rev()` function is asked to dereference the tip name, it\nallocates memory. But when it turns out that another tip already\ndescribed the commit better than the current one, we forgot to release\nthe memory.\n\nPointed out by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/name-rev.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 92a5d8a5d26..a4ce73fb1e9 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n \tstruct rev_name *name = (struct rev_name *)commit->util;\n \tstruct commit_list *parents;\n \tint parent_number = 1;\n+\tchar *p = NULL;\n \n \tparse_commit(commit);\n \n@@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n \t\treturn;\n \n \tif (deref) {\n-\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n+\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n \n \t\tif (generation)\n \t\t\tdie(\"generation: %d, but deref?\", generation);\n@@ -53,8 +54,10 @@ static void name_rev(struct commit *commit,\n \t\tname->taggerdate = taggerdate;\n \t\tname->generation = generation;\n \t\tname->distance = distance;\n-\t} else\n+\t} else {\n+\t\tfree(p);\n \t\treturn;\n+\t}\n \n \tfor (parents = commit->parents;\n \t\t\tparents;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318177","messageId":"61752ef33781402fe90dfa92dee2427e3cd00e5b.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 24/25] show_worktree(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:42Z","receivedAt":"2017-04-28T14:04:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The buffer allocated by shorten_unambiguous_ref() needs to be released.\n\nDiscovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/worktree.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 1722a9bdc2a..ff5dfd2b102 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -414,9 +414,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)\n \t\t\t\tfind_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));\n \t\tif (wt->is_detached)\n \t\t\tstrbuf_addstr(&sb, \"(detached HEAD)\");\n-\t\telse if (wt->head_ref)\n-\t\t\tstrbuf_addf(&sb, \"[%s]\", shorten_unambiguous_ref(wt->head_ref, 0));\n-\t\telse\n+\t\telse if (wt->head_ref) {\n+\t\t\tchar *ref = shorten_unambiguous_ref(wt->head_ref, 0);\n+\t\t\tstrbuf_addf(&sb, \"[%s]\", ref);\n+\t\t\tfree(ref);\n+\t\t} else\n \t\t\tstrbuf_addstr(&sb, \"(error)\");\n \t}\n \tprintf(\"%s\\n\", sb.buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318178","messageId":"f3a803b812e74c7ea4166fdc443a16129784d133.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 25/25] submodule_uses_worktrees(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:46Z","receivedAt":"2017-04-28T14:05:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"There is really no reason why we would need to hold onto the allocated\nstring longer than necessary.\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n worktree.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/worktree.c b/worktree.c\nindex bae787cf8d7..89a81b13de3 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -399,6 +399,7 @@ int submodule_uses_worktrees(const char *path)\n \n \t/* The env would be set for the superproject. */\n \tget_common_dir_noenv(&sb, submodule_gitdir);\n+\tfree(submodule_gitdir);\n \n \t/*\n \t * The check below is only known to be good for repository format\n@@ -418,7 +419,6 @@ int submodule_uses_worktrees(const char *path)\n \t/* See if there is any file inside the worktrees directory. */\n \tdir = opendir(sb.buf);\n \tstrbuf_release(&sb);\n-\tfree(submodule_gitdir);\n \n \tif (!dir)\n \t\treturn 0;\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318179","messageId":"8d0c58714830e7c4566382f94617848b411b5535.1493387231.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v2 21/25] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T14:04:18Z","receivedAt":"2017-04-28T14:06:32Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"We free()d the `log` buffer when dwim_log() returned 1, but not when it\nreturned a larger value (which meant that it still allocated the buffer\nbut we simply ignored it).\n\nWhile in the vicinity, make sure that the `reflogs` structure as well as\nthe `branch` variable are released properly, too.\n\nIdentified by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n reflog-walk.c | 20 +++++++++++++++++---\n 1 file changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 99679f58255..c63eb1a3fd7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tif (!reflogs || reflogs->nr == 0) {\n \t\t\tstruct object_id oid;\n \t\t\tchar *b;\n-\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {\n+\t\t\tint ret = dwim_log(branch, strlen(branch),\n+\t\t\t\t\t   oid.hash, &b);\n+\t\t\tif (ret > 1)\n+\t\t\t\tfree(b);\n+\t\t\telse if (ret == 1) {\n \t\t\t\tif (reflogs) {\n \t\t\t\t\tfree(reflogs->ref);\n \t\t\t\t\tfree(reflogs);\n@@ -193,17 +197,27 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\t\t\treflogs = read_complete_reflog(branch);\n \t\t\t}\n \t\t}\n-\t\tif (!reflogs || reflogs->nr == 0)\n+\t\tif (!reflogs || reflogs->nr == 0) {\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n+\t\t\tfree(branch);\n \t\t\treturn -1;\n+\t\t}\n \t\tstring_list_insert(&info->complete_reflogs, branch)->util\n \t\t\t= reflogs;\n \t}\n+\tfree(branch);\n \n \tcommit_reflog = xcalloc(1, sizeof(struct commit_reflog));\n \tif (recno < 0) {\n \t\tcommit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);\n \t\tif (commit_reflog->recno < 0) {\n-\t\t\tfree(branch);\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n \t\t\tfree(commit_reflog);\n \t\t\treturn -1;\n \t\t}\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318193","messageId":"CAGZ79kYOp1deMgcEB3HHXeEcLOKNs4KPjdT_W2CD+4Amduv2Wg@mail.gmail.com","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704280010160.3480@virtualbox","subject":"Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-04-28T18:05:17Z","receivedAt":"2017-04-28T18:05:23Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"Hi Johannes,\n\nthanks for the reply.\n\nOn Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n\n> I still have to find the time to figure out one more detail: how to\n> download and extract the Coverity tool (the .zip archive has a variable\n> name for the top-level directory), and doing that only every once\n> in a while, say, only when there is no previously unpacked tool, or it is\n> already 4 weeks old.\n\nThat is an interesting problem, which I ignored as the older versions of their\ntools still works once they release new versions. So I just manually check\nevery once in a while if they have new versions out there.\n\nSo if you find a nice solution to that problem, let me know, please.\n\nThanks,\nStefan\n"},{"id":"318199","messageId":"alpine.DEB.2.20.1704282205320.3480@virtualbox","threadId":"45809","inReplyTo":"CAGZ79kYOp1deMgcEB3HHXeEcLOKNs4KPjdT_W2CD+4Amduv2Wg@mail.gmail.com","subject":"Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-04-28T20:29:30Z","receivedAt":"2017-04-28T20:29:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\nOn Fri, 28 Apr 2017, Stefan Beller wrote:\n\n> On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> \n> > I still have to find the time to figure out one more detail: how to\n> > download and extract the Coverity tool (the .zip archive has a\n> > variable name for the top-level directory), and doing that only every\n> > once in a while, say, only when there is no previously unpacked tool,\n> > or it is already 4 weeks old.\n> \n> That is an interesting problem, which I ignored as the older versions of\n> their tools still works once they release new versions. So I just\n> manually check every once in a while if they have new versions out\n> there.\n> \n> So if you find a nice solution to that problem, let me know, please.\n\nI think I have a working idea (jotting it down in the editor, untested):\n\n\tinit_or_update_coverity_tool () {\n\t\t# check once per week whether there is a new version\n\t\tcoverity_tool=.git/coverity-tool/\n\t\ttest ! -d $coverity_tool ||\n\t\ttest $(($(date +%s)-$(stat -c %Y $coverity_tool))) -gt\n\t\t\t$((7*24*60*60)) ||\n\t\treturn\n\n\t\tcurl --form \"token=$(COVERITY.TOKEN)\" \\\n\t\t\t--form \"project=git-for-windows\" \\\n\t\t\t--time-cond .git/coverity_tool.zip \\\n\t\t\t-o .git/coverity_tool.zip.new \\\n\t\t\thttps://scan.coverity.com/download/win64 &&\n\t\ttest -f .git/coverity_tool.zip.new || {\n\t\t\t# Try again in a week\n\t\t\ttouch $coverity_tool\n\t\t\treturn\n\t\t}\n\n\t\tmv -f .git/coverity_tool.zip.new .git/coverity_tool.zip ||\n\t\tdie \"Could not overwrite coverity_tool.zip\"\n\n\t\tmkdir $coverity_tool.new &&\n\t\t(cd $coverity_tool.new &&\n\t\t unzip ../coverity_tool.zip) ||\n\t\tdie \"Could not unpack coverity_tool.zip\"\n\n\t\trm -rf $coverity_tool &&\n\t\tmv $coverity_tool.new $coverity_tool ||\n\t\tdie \"Could not switch to new Coverity tool version\"\n\t}\n\n\tinit_or_update_coverity_tool\n\tPATH=$(echo $coverity_tool/*/bin):$PATH\n\nI guess I will start from that snippet once I have time to work on that\nCoverity automation.\n\nBTW I stumbled over an interesting tidbit today: if you define FLEX_ARRAY\noutside of git-compat-util.h, it will not be overridden by Git. That is,\nif you want to use 64kB flex arrays by default, you can call\n\n\tmake CPPFLAGS=-DFLEX_ARRAY=65536\n\nNo need to patch the source code.\n\nCiao,\nDscho\n"},{"id":"318278","messageId":"xmqqh915jrw2.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704281117040.3480@virtualbox","subject":"Re: [PATCH 07/26] http-backend: avoid memory leaks","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-01T01:19:09Z","receivedAt":"2017-05-01T01:19:16Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> Hmph.  I find a \"leak\" of a resource acquired inside the main\n>> function and not released when the main function leaves a lot less\n>> interesting than the other ones this series covers.\n>\n> Ah, I missed that this falls squarely into the \"one-shot programs are\n> allowed to be sloppy in their memory management, essentially using exit()\n> as garbage collector\" category.\n\nI actually think it was a good intention of yours and I would agree\nwith the patch.  The automated tools that find and complain about\nthese issues do not know about our local house rules like \"do not\nbother freeing immediately before exit\" and will keep notifying us\nof leaks. One way to reduce the noise level so that we can focus on\nreal issues they may find for us in the future is to squelch these\n\"uninteresting\" ones by \"fixing\" them, even if our local house rule\nsays OK, like this patch does.\n\nI said \"a lot less interesting\" and did not mean \"it is bad for our\ncode to do this\".\n\nThanks.\n"},{"id":"318360","messageId":"73A81857-0083-4A70-88AE-FAA025B6A4B7@gmail.com","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704282205320.3480@virtualbox","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Lars Schneider","fromEmail":"larsxschneider@gmail.com","sentAt":"2017-05-01T11:22:10Z","receivedAt":"2017-05-01T11:22:18Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"\n> On 28 Apr 2017, at 22:29, Johannes Schindelin <johannes.schindelin@gmx.de> wrote:\n> \n> Hi Stefan,\n> \n> On Fri, 28 Apr 2017, Stefan Beller wrote:\n> \n>> On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>> \n>>> I still have to find the time to figure out one more detail: how to\n>>> download and extract the Coverity tool (the .zip archive has a\n>>> variable name for the top-level directory), and doing that only every\n>>> once in a while, say, only when there is no previously unpacked tool,\n>>> or it is already 4 weeks old.\n>> \n>> That is an interesting problem, which I ignored as the older versions of\n>> their tools still works once they release new versions. So I just\n>> manually check every once in a while if they have new versions out\n>> there.\n>> \n>> So if you find a nice solution to that problem, let me know, please.\n> \n> I think I have a working idea (jotting it down in the editor, untested):\n> \n> \tinit_or_update_coverity_tool () {\n> \t\t# check once per week whether there is a new version\n> \t\tcoverity_tool=.git/coverity-tool/\n> \t\ttest ! -d $coverity_tool ||\n> \t\ttest $(($(date +%s)-$(stat -c %Y $coverity_tool))) -gt\n> \t\t\t$((7*24*60*60)) ||\n> \t\treturn\n> \n> \t\tcurl --form \"token=$(COVERITY.TOKEN)\" \\\n> \t\t\t--form \"project=git-for-windows\" \\\n> \t\t\t--time-cond .git/coverity_tool.zip \\\n> \t\t\t-o .git/coverity_tool.zip.new \\\n> \t\t\thttps://scan.coverity.com/download/win64 &&\n> \t\ttest -f .git/coverity_tool.zip.new || {\n> \t\t\t# Try again in a week\n> \t\t\ttouch $coverity_tool\n> \t\t\treturn\n> \t\t}\n> \n> \t\tmv -f .git/coverity_tool.zip.new .git/coverity_tool.zip ||\n> \t\tdie \"Could not overwrite coverity_tool.zip\"\n> \n> \t\tmkdir $coverity_tool.new &&\n> \t\t(cd $coverity_tool.new &&\n> \t\t unzip ../coverity_tool.zip) ||\n> \t\tdie \"Could not unpack coverity_tool.zip\"\n> \n> \t\trm -rf $coverity_tool &&\n> \t\tmv $coverity_tool.new $coverity_tool ||\n> \t\tdie \"Could not switch to new Coverity tool version\"\n> \t}\n> \n> \tinit_or_update_coverity_tool\n> \tPATH=$(echo $coverity_tool/*/bin):$PATH\n> \n> I guess I will start from that snippet once I have time to work on that\n> Coverity automation.\n> \n> BTW I stumbled over an interesting tidbit today: if you define FLEX_ARRAY\n> outside of git-compat-util.h, it will not be overridden by Git. That is,\n> if you want to use 64kB flex arrays by default, you can call\n> \n> \tmake CPPFLAGS=-DFLEX_ARRAY=65536\n> \n> No need to patch the source code.\n\nLooks like Coverity has TravisCI integration and I assume you wouldn't\nneed to worry about downloading the tool in that setup:\nhttps://scan.coverity.com/travis_ci\n\nI think we should be able to enable it without trouble for the 'master' branch?\n\nCheers,\nLars"},{"id":"318393","messageId":"alpine.DEB.2.20.1705011358260.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqh915jrw2.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH 07/26] http-backend: avoid memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-01T19:05:38Z","receivedAt":"2017-05-01T19:06:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Sun, 30 Apr 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \n> >> Hmph.  I find a \"leak\" of a resource acquired inside the main\n> >> function and not released when the main function leaves a lot less\n> >> interesting than the other ones this series covers.\n> >\n> > Ah, I missed that this falls squarely into the \"one-shot programs are\n> > allowed to be sloppy in their memory management, essentially using\n> > exit() as garbage collector\" category.\n> \n> I actually think it was a good intention of yours and I would agree\n> with the patch.  The automated tools that find and complain about\n> these issues do not know about our local house rules like \"do not\n> bother freeing immediately before exit\" and will keep notifying us\n> of leaks.\n\nIn Coverity, I marked them as \"Intentional\", so that they can be dropped\nfrom the default view.\n\nUnfortunately, the verdict \"Intentional\" does not percolate to other\nprojects, so I will probably have to do the entire shebang in the `git`\nproject again.\n\nOf course, we could also decide that we want to shut up static analyzers\nby actually *not* leaking memory, by *not* using exit() as our garbage\ncollector in one-shot commands, with the added benefit of making the code\neasier to libify/reuse.\n\nBut I fear that I distract the discussion away from a more focused\nattention to the actual patch series, which is actually still in flight\nand in actual need for review, as I actually want to get those patches\nintegrated into git.git.\n\nCiao,\nDscho\n"},{"id":"318456","messageId":"xmqqlgqgdk11.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"f3a803b812e74c7ea4166fdc443a16129784d133.1493387231.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 25/25] submodule_uses_worktrees(): plug memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T03:17:46Z","receivedAt":"2017-05-02T03:17:59Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> There is really no reason why we would need to hold onto the allocated\n> string longer than necessary.\n\nYup.  The longer we make the duration between the allocation and the\nstandard release, the more likely future code would add early returns\nthat forget to release the memory.\n\nLooks correct; will queue.\n\n\n> Reported by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  worktree.c | 2 +-\n>  1 file changed, 1 insertion(+), 1 deletion(-)\n>\n> diff --git a/worktree.c b/worktree.c\n> index bae787cf8d7..89a81b13de3 100644\n> --- a/worktree.c\n> +++ b/worktree.c\n> @@ -399,6 +399,7 @@ int submodule_uses_worktrees(const char *path)\n>  \n>  \t/* The env would be set for the superproject. */\n>  \tget_common_dir_noenv(&sb, submodule_gitdir);\n> +\tfree(submodule_gitdir);\n>  \n>  \t/*\n>  \t * The check below is only known to be good for repository format\n> @@ -418,7 +419,6 @@ int submodule_uses_worktrees(const char *path)\n>  \t/* See if there is any file inside the worktrees directory. */\n>  \tdir = opendir(sb.buf);\n>  \tstrbuf_release(&sb);\n> -\tfree(submodule_gitdir);\n>  \n>  \tif (!dir)\n>  \t\treturn 0;\n"},{"id":"318457","messageId":"xmqqh914djth.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"61752ef33781402fe90dfa92dee2427e3cd00e5b.1493387231.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 24/25] show_worktree(): plug memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T03:22:18Z","receivedAt":"2017-05-02T03:22:25Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> The buffer allocated by shorten_unambiguous_ref() needs to be released.\n\nYes.  Looks good.\n\n>\n> Discovered by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/worktree.c | 8 +++++---\n>  1 file changed, 5 insertions(+), 3 deletions(-)\n>\n> diff --git a/builtin/worktree.c b/builtin/worktree.c\n> index 1722a9bdc2a..ff5dfd2b102 100644\n> --- a/builtin/worktree.c\n> +++ b/builtin/worktree.c\n> @@ -414,9 +414,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)\n>  \t\t\t\tfind_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));\n>  \t\tif (wt->is_detached)\n>  \t\t\tstrbuf_addstr(&sb, \"(detached HEAD)\");\n> -\t\telse if (wt->head_ref)\n> -\t\t\tstrbuf_addf(&sb, \"[%s]\", shorten_unambiguous_ref(wt->head_ref, 0));\n> -\t\telse\n> +\t\telse if (wt->head_ref) {\n> +\t\t\tchar *ref = shorten_unambiguous_ref(wt->head_ref, 0);\n> +\t\t\tstrbuf_addf(&sb, \"[%s]\", ref);\n> +\t\t\tfree(ref);\n> +\t\t} else\n>  \t\t\tstrbuf_addstr(&sb, \"(error)\");\n>  \t}\n>  \tprintf(\"%s\\n\", sb.buf);\n"},{"id":"318458","messageId":"xmqqd1bsdjmw.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"9e897d6f263bcf9a2b2bab613946fe1bf452eb91.1493387231.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T03:26:15Z","receivedAt":"2017-05-02T03:26:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> When the `name_rev()` function is asked to dereference the tip name, it\n> allocates memory. But when it turns out that another tip already\n> described the commit better than the current one, we forgot to release\n> the memory.\n\nVery well explained.\n\n>\n> Pointed out by Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/name-rev.c | 7 +++++--\n>  1 file changed, 5 insertions(+), 2 deletions(-)\n>\n> diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n> index 92a5d8a5d26..a4ce73fb1e9 100644\n> --- a/builtin/name-rev.c\n> +++ b/builtin/name-rev.c\n> @@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n>  \tstruct rev_name *name = (struct rev_name *)commit->util;\n>  \tstruct commit_list *parents;\n>  \tint parent_number = 1;\n> +\tchar *p = NULL;\n>  \n>  \tparse_commit(commit);\n>  \n> @@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n>  \t\treturn;\n>  \n>  \tif (deref) {\n> -\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n> +\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n>  \n>  \t\tif (generation)\n>  \t\t\tdie(\"generation: %d, but deref?\", generation);\n> @@ -53,8 +54,10 @@ static void name_rev(struct commit *commit,\n>  \t\tname->taggerdate = taggerdate;\n>  \t\tname->generation = generation;\n>  \t\tname->distance = distance;\n> -\t} else\n> +\t} else {\n> +\t\tfree(p);\n>  \t\treturn;\n> +\t}\n>  \n>  \tfor (parents = commit->parents;\n>  \t\t\tparents;\n"},{"id":"318459","messageId":"xmqq8tmfexg6.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"xmqqd1bsdjmw.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T03:42:33Z","receivedAt":"2017-05-02T03:42:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n>\n>> When the `name_rev()` function is asked to dereference the tip name, it\n>> allocates memory. But when it turns out that another tip already\n>> described the commit better than the current one, we forgot to release\n>> the memory.\n>\n> Very well explained.\n>>\n>> diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n>> index 92a5d8a5d26..a4ce73fb1e9 100644\n>> --- a/builtin/name-rev.c\n>> +++ b/builtin/name-rev.c\n>> @@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n>>  \tstruct rev_name *name = (struct rev_name *)commit->util;\n>>  \tstruct commit_list *parents;\n>>  \tint parent_number = 1;\n>> +\tchar *p = NULL;\n>>  \n>>  \tparse_commit(commit);\n>>  \n>> @@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n>>  \t\treturn;\n>>  \n>>  \tif (deref) {\n>> -\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n>> +\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n\nI'll rename 'p' to 'to_free' while queuing, though.  Without a\ndescriptive name, it was confusing to view while resolving conflicts\nwith another in-flight topic.\n"},{"id":"318460","messageId":"xmqq4lx3ewrc.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"cbd8e917f1318190d9f979f4cc9b62dcd838bbb0.1493387231.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 14/25] setup_discovered_git_dir(): help static analysis","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T03:57:27Z","receivedAt":"2017-05-02T03:57:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> Coverity reported a memory leak in this function. However, it can only\n> be called once, as setup_git_directory() changes global state and hence\n> is not reentrant.\n>\n> Mark the variable as static to indicate that this is a singleton.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n\nDoes something different from what is explained above.  Rebase gotcha?\n\n>  setup.c | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n>\n> diff --git a/setup.c b/setup.c\n> index 0320a9ad14c..12efca85a41 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n>  \n>  \t/* --work-tree is set without --git-dir; use discovered one */\n>  \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> +\t\tchar *p = NULL;\n> +\t\tconst char *ret;\n> +\n>  \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n> -\t\t\tgitdir = real_pathdup(gitdir, 1);\n> +\t\t\tgitdir = p = real_pathdup(gitdir, 1);\n>  \t\tif (chdir(cwd->buf))\n>  \t\t\tdie_errno(\"Could not come back to cwd\");\n> -\t\treturn setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n> +\t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n> +\t\tfree(p);\n> +\t\treturn ret;\n>  \t}\n>  \n>  \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n"},{"id":"318469","messageId":"xmqqzievdhk5.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"32a2d16902734c8794de61b5e86a0d2a6cf43fa3.1493387231.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v2 09/25] mailinfo & mailsplit: check for EOF while parsing","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-02T04:11:06Z","receivedAt":"2017-05-02T04:11:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n\n> While POSIX states that it is okay to pass EOF to isspace() (and it seems\n> to be implied that EOF should *not* be treated as whitespace), and also to\n> pass EOF to ungetc() (which seems to be intended to fail without buffering\n> the character), it is much better to handle these cases explicitly. Not\n> only does it reduce head-scratching (and helps static analysis avoid\n> reporting false positives), it also lets us handle files containing\n> nothing but whitespace by erroring out.\n>\n> Reported via Coverity.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  builtin/mailsplit.c |  3 ++-\n>  mailinfo.c          | 15 +++++++++++----\n>  2 files changed, 13 insertions(+), 5 deletions(-)\n>\n> diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> index 30681681c13..9b3efc8e987 100644\n> --- a/builtin/mailsplit.c\n> +++ b/builtin/mailsplit.c\n> @@ -233,7 +233,8 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n>  \tdo {\n>  \t\tpeek = fgetc(f);\n>  \t} while (isspace(peek));\n> -\tungetc(peek, f);\n> +\tif (peek != EOF)\n> +\t\tungetc(peek, f);\n\nI agree more with the first sentence in the proposed log message\nthan what this code actually does.  I.e. breaking upon seeing an EOF\nexplicitly would be nice, just like the change to mailinfo.c in this\npatch we see below.\n\n> @@ -1094,14 +1097,18 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n>  \t\treturn -1;\n>  \t}\n>  \n> -\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n> -\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n> -\n>  \tdo {\n>  \t\tpeek = fgetc(mi->input);\n> +\t\tif (peek == EOF) {\n> +\t\t\tfclose(cmitmsg);\n> +\t\t\treturn error(\"empty patch: '%s'\", patch);\n> +\t\t}\n>  \t} while (isspace(peek));\n>  \tungetc(peek, mi->input);\n\nThe handling of EOF is improved, but is it correct to move the\nallocation of p/s_hdr_data down?\n\nAmong the two callers, builtin/am.c just dies when it sees\nmailinfo() returns an error, but builtin/mailinfo.c tries to be\nnicer and calls clear_mailinfo().  Wouldn't this make that codepath\ndereference a NULL pointer?\n\nI think the moral of the story is that people tend to get sloppier\nwhen doing \"while we are at it\" than the main task, and a reviewer\nneeds to be more careful while reviewing the \"while we are at it\"\npart of the change than the primary thing a patch wants to do ;-)\n\n> +\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n> +\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n> +\n>  \t/* process the email header */\n>  \twhile (read_one_header_line(&line, mi->input))\n>  \t\tcheck_header(mi, &line, mi->p_hdr_data, 1);\n"},{"id":"318484","messageId":"alpine.DEB.2.20.1705021345100.3480@virtualbox","threadId":"45809","inReplyTo":"73A81857-0083-4A70-88AE-FAA025B6A4B7@gmail.com","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T11:46:16Z","receivedAt":"2017-05-02T11:46:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Lars,\n\nOn Mon, 1 May 2017, Lars Schneider wrote:\n\n> Looks like Coverity has TravisCI integration and I assume you wouldn't\n> need to worry about downloading the tool in that setup:\n> https://scan.coverity.com/travis_ci\n\nExcept for that tiny little fact that Travis CI does not support Windows\nbackends (nor would they even respond to my offer to work with them).\n\nCiao,\nDscho\n"},{"id":"318496","messageId":"alpine.DEB.2.20.1705021438300.3480@virtualbox","threadId":"45809","inReplyTo":"xmqq4lx3ewrc.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 14/25] setup_discovered_git_dir(): help static analysis","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T12:38:55Z","receivedAt":"2017-05-02T12:39:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 1 May 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > Coverity reported a memory leak in this function. However, it can only\n> > be called once, as setup_git_directory() changes global state and hence\n> > is not reentrant.\n> >\n> > Mark the variable as static to indicate that this is a singleton.\n> >\n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> \n> Does something different from what is explained above.  Rebase gotcha?\n\nThat, or just a brain fart.\n\nThanks, will send an updated iteration.\n\nCiao,\nDscho\n"},{"id":"318499","messageId":"alpine.DEB.2.20.1705021553420.3480@virtualbox","threadId":"45809","inReplyTo":"xmqqzievdhk5.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 09/25] mailinfo & mailsplit: check for EOF while parsing","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T13:57:19Z","receivedAt":"2017-05-02T13:58:00Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 1 May 2017, Junio C Hamano wrote:\n\n> Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> \n> > diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n> > index 30681681c13..9b3efc8e987 100644\n> > --- a/builtin/mailsplit.c\n> > +++ b/builtin/mailsplit.c\n> > @@ -233,7 +233,8 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n> >  \tdo {\n> >  \t\tpeek = fgetc(f);\n> >  \t} while (isspace(peek));\n> > -\tungetc(peek, f);\n> > +\tif (peek != EOF)\n> > +\t\tungetc(peek, f);\n> \n> I agree more with the first sentence in the proposed log message\n> than what this code actually does.  I.e. breaking upon seeing an EOF\n> explicitly would be nice, just like the change to mailinfo.c in this\n> patch we see below.\n\nI changed it to error out with a (translated) \"empty mbox: '%s'\" as the\nother hunks.\n\n> > @@ -1094,14 +1097,18 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n> >  \t\treturn -1;\n> >  \t}\n> >  \n> > -\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n> > -\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n> > -\n> >  \tdo {\n> >  \t\tpeek = fgetc(mi->input);\n> > +\t\tif (peek == EOF) {\n> > +\t\t\tfclose(cmitmsg);\n> > +\t\t\treturn error(\"empty patch: '%s'\", patch);\n> > +\t\t}\n> >  \t} while (isspace(peek));\n> >  \tungetc(peek, mi->input);\n> \n> The handling of EOF is improved, but is it correct to move the\n> allocation of p/s_hdr_data down?\n\nSorry, I *assumed* that the function was passed a zero-initialized\nmailinfo struct. And as you pointed out, that assumption was wrong.\n\nMy thinking was that I did not want to introduce another leakage by my\npatch, but as your careful analysis determined: the only caller that does\nnot die() afterwards releases the data (and would not even be able to\nhandle p_hdr_data == NULL...).\n\nI reverted that move.\n\nCiao,\nDscho\n"},{"id":"318500","messageId":"alpine.DEB.2.20.1705021433060.3480@virtualbox","threadId":"45809","inReplyTo":"xmqq8tmfexg6.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T14:00:44Z","receivedAt":"2017-05-02T14:01:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Mon, 1 May 2017, Junio C Hamano wrote:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n> \n> > Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n> >\n> >> diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n> >> index 92a5d8a5d26..a4ce73fb1e9 100644\n> >> --- a/builtin/name-rev.c\n> >> +++ b/builtin/name-rev.c\n> >> @@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n> >>  \tstruct rev_name *name = (struct rev_name *)commit->util;\n> >>  \tstruct commit_list *parents;\n> >>  \tint parent_number = 1;\n> >> +\tchar *p = NULL;\n> >>  \n> >>  \tparse_commit(commit);\n> >>  \n> >> @@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n> >>  \t\treturn;\n> >>  \n> >>  \tif (deref) {\n> >> -\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n> >> +\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n> \n> I'll rename 'p' to 'to_free' while queuing, though.  Without a\n> descriptive name, it was confusing to view while resolving conflicts\n> with another in-flight topic.\n\nGood point. I also used `p` in builtin/mktree.c and setup.c. While you\nseem to have renamed it in builtin/mktree.c, I think setup.c also needs\nthe same fixup.\n\nCiao,\nDscho\n"},{"id":"318512","messageId":"cover.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493387231.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 00/25] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:00:30Z","receivedAt":"2017-05-02T16:00:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"I recently registered the git-for-windows fork with Coverity to ensure\nthat even the Windows-specific patches get some static analysis love.\n\nWhile at it, I squashed a couple of obvious issues in the part that is\nnot Windows-specific.\n\nNote: while this patch series squashes some of those issues, the\nremaining issues are not necessarily all false positives (e.g. Coverity\ngetting fooled by our FLEX_ARRAY trick into believing that the last\nmember of the struct is indeed a 0 or 1 size array) or intentional (e.g.\nbuiltins not releasing memory because exit() is called right after\nreturning from the function that leaks memory).\n\nNotable examples of the remaining issues are:\n\n- a couple of callers of shorten_unambiguous_ref() assume that they do\n  not have to release the memory returned from that function, often\n  assigning the pointer to a `const` variable that typically does not\n  hold a pointer that needs to be free()d. My hunch is that we will want\n  to convert that function to have a fixed number of static buffers and\n  use those in a round robin fashion à la sha1_to_hex().\n\n- pack-redundant.c seems to have hard-to-reason-about code paths that\n  may eventually leak memory. Essentially, the custody of the allocated\n  memory is not clear at all.\n\n- fast-import.c calls strbuf_detach() on the command_buf without any\n  obvious rationale. Turns out that *some* code paths assign\n  command_buf.buf to a `recent_command` which releases the buffer later.\n  However, from a cursory look it appears to me as if there are some\n  other code paths that skip that assignment, effectively causing a memory\n  leak once strbuf_detach() is called.\n\nSadly, I lack the time to pursue those remaining issues further.\n\nChanges since v2:\n\n- renamed the `p` variables introduced by the patch series to the more\n  explanatory `to_free`.\n\n- reworded incorrect commit message claiming that\n  setup_discovered_git_dir() was using a static variable that is\n  actually a singleton\n\n- reverted a code move that would have resulted in accessing\n  uninitialized data of callers of mailinfo() that do not die() right\n  away but clean up faithfully\n\n\nJohannes Schindelin (25):\n  mingw: avoid memory leak when splitting PATH\n  winansi: avoid use of uninitialized value\n  winansi: avoid buffer overrun\n  add_commit_patch_id(): avoid allocating memory unnecessarily\n  git_config_rename_section_in_file(): avoid resource leak\n  get_mail_commit_oid(): avoid resource leak\n  difftool: address a couple of resource/memory leaks\n  status: close file descriptor after reading git-rebase-todo\n  mailinfo & mailsplit: check for EOF while parsing\n  cat-file: fix memory leak\n  checkout: fix memory leak\n  split_commit_in_progress(): fix memory leak\n  setup_bare_git_dir(): help static analysis\n  setup_discovered_git_dir(): plug memory leak\n  pack-redundant: plug memory leak\n  mktree: plug memory leaks reported by Coverity\n  fast-export: avoid leaking memory in handle_tag()\n  receive-pack: plug memory leak in update()\n  line-log: avoid memory leak\n  shallow: avoid memory leak\n  add_reflog_for_walk: avoid memory leak\n  remote: plug memory leak in match_explicit()\n  name-rev: avoid leaking memory in the `deref` case\n  show_worktree(): plug memory leak\n  submodule_uses_worktrees(): plug memory leak\n\n builtin/am.c             | 15 ++++++---------\n builtin/cat-file.c       |  1 +\n builtin/checkout.c       | 17 +++++++++--------\n builtin/difftool.c       | 33 +++++++++++++++++++++++----------\n builtin/fast-export.c    |  2 ++\n builtin/mailsplit.c      | 10 ++++++++++\n builtin/mktree.c         |  5 +++--\n builtin/name-rev.c       |  7 +++++--\n builtin/pack-redundant.c |  1 +\n builtin/receive-pack.c   |  4 +++-\n builtin/worktree.c       |  8 +++++---\n compat/mingw.c           |  4 +++-\n compat/winansi.c         |  7 +++++++\n config.c                 |  5 ++++-\n line-log.c               |  1 +\n mailinfo.c               |  9 ++++++++-\n patch-ids.c              |  3 ++-\n reflog-walk.c            | 20 +++++++++++++++++---\n remote.c                 |  5 +++--\n setup.c                  | 11 ++++++++---\n shallow.c                |  8 ++++++--\n worktree.c               |  2 +-\n wt-status.c              |  8 +++++++-\n 23 files changed, 135 insertions(+), 51 deletions(-)\n\n\nbase-commit: d2bbb7c2bcf6e77ebfcabf4e12110fe6d5c91de6\nPublished-As: https://github.com/dscho/git/releases/tag/coverity-v3\nFetch-It-Via: git fetch https://github.com/dscho/git coverity-v3\n\nInterdiff vs v2:\n\n diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\n index 9b3efc8e987..664400b8169 100644\n --- a/builtin/mailsplit.c\n +++ b/builtin/mailsplit.c\n @@ -232,9 +232,18 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n  \n  \tdo {\n  \t\tpeek = fgetc(f);\n +\t\tif (peek == EOF) {\n +\t\t\tif (f == stdin)\n +\t\t\t\t/* empty stdin is OK */\n +\t\t\t\tret = skip;\n +\t\t\telse {\n +\t\t\t\tfclose(f);\n +\t\t\t\terror(_(\"empty mbox: '%s'\"), file);\n +\t\t\t}\n +\t\t\tgoto out;\n +\t\t}\n  \t} while (isspace(peek));\n -\tif (peek != EOF)\n -\t\tungetc(peek, f);\n +\tungetc(peek, f);\n  \n  \tif (strbuf_getwholeline(&buf, f, '\\n')) {\n  \t\t/* empty stdin is OK */\n diff --git a/builtin/mktree.c b/builtin/mktree.c\n index f0354bc9718..da0fd8cd706 100644\n --- a/builtin/mktree.c\n +++ b/builtin/mktree.c\n @@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n  \tunsigned mode;\n  \tenum object_type mode_type; /* object type derived from mode */\n  \tenum object_type obj_type; /* object type derived from sha */\n -\tchar *path, *p = NULL;\n +\tchar *path, *to_free = NULL;\n  \tunsigned char sha1[20];\n  \n  \tptr = buf;\n @@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n  \t\tstruct strbuf p_uq = STRBUF_INIT;\n  \t\tif (unquote_c_style(&p_uq, path, NULL))\n  \t\t\tdie(\"invalid quoting\");\n -\t\tpath = p = strbuf_detach(&p_uq, NULL);\n +\t\tpath = to_free = strbuf_detach(&p_uq, NULL);\n  \t}\n  \n  \t/*\n @@ -136,7 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n  \t}\n  \n  \tappend_to_tree(mode, sha1, path);\n -\tfree(p);\n +\tfree(to_free);\n  }\n  \n  int cmd_mktree(int ac, const char **av, const char *prefix)\n diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n index a4ce73fb1e9..e7a3fe7ee70 100644\n --- a/builtin/name-rev.c\n +++ b/builtin/name-rev.c\n @@ -28,7 +28,7 @@ static void name_rev(struct commit *commit,\n  \tstruct rev_name *name = (struct rev_name *)commit->util;\n  \tstruct commit_list *parents;\n  \tint parent_number = 1;\n -\tchar *p = NULL;\n +\tchar *to_free = NULL;\n  \n  \tparse_commit(commit);\n  \n @@ -36,7 +36,7 @@ static void name_rev(struct commit *commit,\n  \t\treturn;\n  \n  \tif (deref) {\n -\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n +\t\ttip_name = to_free = xstrfmt(\"%s^0\", tip_name);\n  \n  \t\tif (generation)\n  \t\t\tdie(\"generation: %d, but deref?\", generation);\n @@ -55,7 +55,7 @@ static void name_rev(struct commit *commit,\n  \t\tname->generation = generation;\n  \t\tname->distance = distance;\n  \t} else {\n -\t\tfree(p);\n +\t\tfree(to_free);\n  \t\treturn;\n  \t}\n  \n diff --git a/mailinfo.c b/mailinfo.c\n index a319911b510..f92cb9f729c 100644\n --- a/mailinfo.c\n +++ b/mailinfo.c\n @@ -1097,6 +1097,9 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n  \t\treturn -1;\n  \t}\n  \n +\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n +\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n +\n  \tdo {\n  \t\tpeek = fgetc(mi->input);\n  \t\tif (peek == EOF) {\n @@ -1106,9 +1109,6 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n  \t} while (isspace(peek));\n  \tungetc(peek, mi->input);\n  \n -\tmi->p_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->p_hdr_data)));\n -\tmi->s_hdr_data = xcalloc(MAX_HDR_PARSED, sizeof(*(mi->s_hdr_data)));\n -\n  \t/* process the email header */\n  \twhile (read_one_header_line(&line, mi->input))\n  \t\tcheck_header(mi, &line, mi->p_hdr_data, 1);\n diff --git a/setup.c b/setup.c\n index 12efca85a41..e3f7699a902 100644\n --- a/setup.c\n +++ b/setup.c\n @@ -703,15 +703,15 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n  \n  \t/* --work-tree is set without --git-dir; use discovered one */\n  \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n -\t\tchar *p = NULL;\n +\t\tchar *to_free = NULL;\n  \t\tconst char *ret;\n  \n  \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n -\t\t\tgitdir = p = real_pathdup(gitdir, 1);\n +\t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n  \t\tif (chdir(cwd->buf))\n  \t\t\tdie_errno(\"Could not come back to cwd\");\n  \t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n -\t\tfree(p);\n +\t\tfree(to_free);\n  \t\treturn ret;\n  \t}\n  \n\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318513","messageId":"10fc0a4a37b4167f49c967ece08f531cb1e8d6b1.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 01/25] mingw: avoid memory leak when splitting PATH","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:00:34Z","receivedAt":"2017-05-02T16:01:02Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In the (admittedly, concocted) case that PATH consists only of colons, we\nwould leak the duplicated string.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 3fbfda5978b..fe0e3ccd248 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -961,8 +961,10 @@ static char **get_path_split(void)\n \t\t\t++n;\n \t\t}\n \t}\n-\tif (!n)\n+\tif (!n) {\n+\t\tfree(envpath);\n \t\treturn NULL;\n+\t}\n \n \tALLOC_ARRAY(path, n + 1);\n \tp = envpath;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318514","messageId":"758b5a5dbe83832db7362246127b8bd1ca7beb9f.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 02/25] winansi: avoid use of uninitialized value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:02Z","receivedAt":"2017-05-02T16:01:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When stdout is not connected to a Win32 console, we incorrectly used an\nuninitialized value for the \"plain\" character attributes.\n\nDetected by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex 793420f9d0d..fd6910746c8 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -105,6 +105,8 @@ static int is_console(int fd)\n \tif (!fd) {\n \t\tif (!GetConsoleMode(hcon, &mode))\n \t\t\treturn 0;\n+\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n+\t\t\tFOREGROUND_RED;\n \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n \t\treturn 0;\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318515","messageId":"8b3b6c1071503df2d3e04162ef7fb5f5ff56b177.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 03/25] winansi: avoid buffer overrun","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:07Z","receivedAt":"2017-05-02T16:01:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we could not convert the UTF-8 sequence into Unicode for writing to\nthe Console, we should not try to write an insanely-long sequence of\ninvalid wide characters (mistaking the negative return value for an\nunsigned length).\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex fd6910746c8..861b79d8c31 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -135,6 +135,11 @@ static void write_console(unsigned char *str, size_t len)\n \n \t/* convert utf-8 to utf-16 */\n \tint wlen = xutftowcsn(wbuf, (char*) str, ARRAY_SIZE(wbuf), len);\n+\tif (wlen < 0) {\n+\t\twchar_t *err = L\"[invalid]\";\n+\t\tWriteConsoleW(console, err, wcslen(err), &dummy, NULL);\n+\t\treturn;\n+\t}\n \n \t/* write directly to console */\n \tWriteConsoleW(console, wbuf, wlen, &dummy, NULL);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318516","messageId":"71aa1c1c90057c59dc6f549b42778a500e908acf.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 04/25] add_commit_patch_id(): avoid allocating memory unnecessarily","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:11Z","receivedAt":"2017-05-02T16:01:27Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"It would appear that we allocate (and forget to release) memory if the\npatch ID is not even defined.\n\nReported by the Coverity tool.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n patch-ids.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/patch-ids.c b/patch-ids.c\nindex fa8f11de826..92eba7a059e 100644\n--- a/patch-ids.c\n+++ b/patch-ids.c\n@@ -99,11 +99,12 @@ struct patch_id *has_commit_patch_id(struct commit *commit,\n struct patch_id *add_commit_patch_id(struct commit *commit,\n \t\t\t\t     struct patch_ids *ids)\n {\n-\tstruct patch_id *key = xcalloc(1, sizeof(*key));\n+\tstruct patch_id *key;\n \n \tif (!patch_id_defined(commit))\n \t\treturn NULL;\n \n+\tkey = xcalloc(1, sizeof(*key));\n \tif (init_patch_id_entry(key, commit, ids)) {\n \t\tfree(key);\n \t\treturn NULL;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318517","messageId":"219203bb33d5229b013e26ff445a8ee1a0ab0aaf.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 06/25] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:29Z","receivedAt":"2017-05-02T16:01:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we fail to read, or parse, the file, we still want to close the file\ndescriptor and release the strbuf.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/am.c | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex a95dd8b4e6c..9c5c2c778e2 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1351,19 +1351,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *fp = xfopen(mail, \"r\");\n \tconst char *x;\n+\tint ret = 0;\n \n-\tif (strbuf_getline_lf(&sb, fp))\n-\t\treturn -1;\n-\n-\tif (!skip_prefix(sb.buf, \"From \", &x))\n-\t\treturn -1;\n-\n-\tif (get_oid_hex(x, commit_id) < 0)\n-\t\treturn -1;\n+\tif (strbuf_getline_lf(&sb, fp) ||\n+\t    !skip_prefix(sb.buf, \"From \", &x) ||\n+\t    get_oid_hex(x, commit_id) < 0)\n+\t\tret = -1;\n \n \tstrbuf_release(&sb);\n \tfclose(fp);\n-\treturn 0;\n+\treturn ret;\n }\n \n /**\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318518","messageId":"04aa5ca2e4c5b3edc0c9dd36b2ecdb4f34e30228.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 07/25] difftool: address a couple of resource/memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:32Z","receivedAt":"2017-05-02T16:01:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change plugs a couple of memory leaks and makes sure that the file\ndescriptor is closed in run_dir_diff().\n\nSpotted by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/difftool.c | 33 +++++++++++++++++++++++----------\n 1 file changed, 23 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex 1354d0e4625..b9a892f2693 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,\n \t\thashmap_entry_init(entry, strhash(buf.buf));\n \t\thashmap_add(result, entry);\n \t}\n+\tfclose(fp);\n \tif (finish_command(&diff_files))\n \t\tdie(\"diff-files did not exit properly\");\n \tstrbuf_release(&index_env);\n@@ -439,8 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \n \t\tif (lmode && status != 'C') {\n-\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate))\n-\t\t\t\treturn error(\"could not write '%s'\", src_path);\n+\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate)) {\n+\t\t\t\tret = error(\"could not write '%s'\", src_path);\n+\t\t\t\tgoto finish;\n+\t\t\t}\n \t\t}\n \n \t\tif (rmode && !S_ISLNK(rmode)) {\n@@ -456,9 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\thashmap_add(&working_tree_dups, entry);\n \n \t\t\tif (!use_wt_file(workdir, dst_path, &roid)) {\n-\t\t\t\tif (checkout_path(rmode, &roid, dst_path, &rstate))\n-\t\t\t\t\treturn error(\"could not write '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (checkout_path(rmode, &roid, dst_path,\n+\t\t\t\t\t\t  &rstate)) {\n+\t\t\t\t\tret = error(\"could not write '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t} else if (!is_null_oid(&roid)) {\n \t\t\t\t/*\n \t\t\t\t * Changes in the working tree need special\n@@ -473,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\t\t\t\tADD_CACHE_JUST_APPEND);\n \n \t\t\t\tadd_path(&rdir, rdir_len, dst_path);\n-\t\t\t\tif (ensure_leading_directories(rdir.buf))\n-\t\t\t\t\treturn error(\"could not create \"\n-\t\t\t\t\t\t     \"directory for '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (ensure_leading_directories(rdir.buf)) {\n+\t\t\t\t\tret = error(\"could not create \"\n+\t\t\t\t\t\t    \"directory for '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t\tadd_path(&wtdir, wtdir_len, dst_path);\n \t\t\t\tif (symlinks) {\n \t\t\t\t\tif (symlink(wtdir.buf, rdir.buf)) {\n@@ -497,13 +505,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \t}\n \n+\tfclose(fp);\n+\tfp = NULL;\n \tif (finish_command(&child)) {\n \t\tret = error(\"error occurred running diff --raw\");\n \t\tgoto finish;\n \t}\n \n \tif (!i)\n-\t\treturn 0;\n+\t\tgoto finish;\n \n \t/*\n \t * Changes to submodules require special treatment.This loop writes a\n@@ -626,6 +636,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\texit_cleanup(tmpdir, rc);\n \n finish:\n+\tif (fp)\n+\t\tfclose(fp);\n+\n \tfree(lbase_dir);\n \tfree(rbase_dir);\n \tstrbuf_release(&ldir);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318519","messageId":"ff873d8c56a5cff786c9964fef71089d3f5e5e59.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 05/25] git_config_rename_section_in_file(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:19Z","receivedAt":"2017-05-02T16:01:46Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In case of errors, we really want the file descriptor to be closed.\n\nDiscovered by a Coverity scan.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.c | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/config.c b/config.c\nindex b4a3205da32..a30056ec7e9 100644\n--- a/config.c\n+++ b/config.c\n@@ -2621,7 +2621,7 @@ int git_config_rename_section_in_file(const char *config_filename,\n \tstruct lock_file *lock;\n \tint out_fd;\n \tchar buf[1024];\n-\tFILE *config_file;\n+\tFILE *config_file = NULL;\n \tstruct stat st;\n \n \tif (new_name && !section_name_is_ok(new_name)) {\n@@ -2703,11 +2703,14 @@ int git_config_rename_section_in_file(const char *config_filename,\n \t\t}\n \t}\n \tfclose(config_file);\n+\tconfig_file = NULL;\n commit_and_out:\n \tif (commit_lock_file(lock) < 0)\n \t\tret = error_errno(\"could not write config file %s\",\n \t\t\t\t  config_filename);\n out:\n+\tif (config_file)\n+\t\tfclose(config_file);\n \trollback_lock_file(lock);\n out_no_rollback:\n \tfree(filename_buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318520","messageId":"6e521e980a282a04ae376363b79bdf5f1e38e313.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 08/25] status: close file descriptor after reading git-rebase-todo","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:36Z","receivedAt":"2017-05-02T16:02:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 03754849626..0a6e16dbe0f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1168,6 +1168,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)\n \t\tabbrev_sha1_in_line(&line);\n \t\tstring_list_append(lines, line.buf);\n \t}\n+\tfclose(f);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318521","messageId":"a27646674c0548c891433945f99891b1bfb5d8a4.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 09/25] mailinfo & mailsplit: check for EOF while parsing","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:54Z","receivedAt":"2017-05-02T16:02:09Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"While POSIX states that it is okay to pass EOF to isspace() (and it seems\nto be implied that EOF should *not* be treated as whitespace), and also to\npass EOF to ungetc() (which seems to be intended to fail without buffering\nthe character), it is much better to handle these cases explicitly. Not\nonly does it reduce head-scratching (and helps static analysis avoid\nreporting false positives), it also lets us handle files containing\nnothing but whitespace by erroring out.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mailsplit.c | 10 ++++++++++\n mailinfo.c          |  9 ++++++++-\n 2 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\nindex 30681681c13..664400b8169 100644\n--- a/builtin/mailsplit.c\n+++ b/builtin/mailsplit.c\n@@ -232,6 +232,16 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n \n \tdo {\n \t\tpeek = fgetc(f);\n+\t\tif (peek == EOF) {\n+\t\t\tif (f == stdin)\n+\t\t\t\t/* empty stdin is OK */\n+\t\t\t\tret = skip;\n+\t\t\telse {\n+\t\t\t\tfclose(f);\n+\t\t\t\terror(_(\"empty mbox: '%s'\"), file);\n+\t\t\t}\n+\t\t\tgoto out;\n+\t\t}\n \t} while (isspace(peek));\n \tungetc(peek, f);\n \ndiff --git a/mailinfo.c b/mailinfo.c\nindex 68037758f2f..f92cb9f729c 100644\n--- a/mailinfo.c\n+++ b/mailinfo.c\n@@ -882,7 +882,10 @@ static int read_one_header_line(struct strbuf *line, FILE *in)\n \tfor (;;) {\n \t\tint peek;\n \n-\t\tpeek = fgetc(in); ungetc(peek, in);\n+\t\tpeek = fgetc(in);\n+\t\tif (peek == EOF)\n+\t\t\tbreak;\n+\t\tungetc(peek, in);\n \t\tif (peek != ' ' && peek != '\\t')\n \t\t\tbreak;\n \t\tif (strbuf_getline_lf(&continuation, in))\n@@ -1099,6 +1102,10 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n \n \tdo {\n \t\tpeek = fgetc(mi->input);\n+\t\tif (peek == EOF) {\n+\t\t\tfclose(cmitmsg);\n+\t\t\treturn error(\"empty patch: '%s'\", patch);\n+\t\t}\n \t} while (isspace(peek));\n \tungetc(peek, mi->input);\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318522","messageId":"c914a7f84b781e81c361f206fe3bc9a4369cc48b.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 10/25] cat-file: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:01:58Z","receivedAt":"2017-05-02T16:02:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/cat-file.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 1890d7a6390..9af863e7915 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \t\tdie(\"git cat-file %s: bad file\", obj_name);\n \n \twrite_or_die(1, buf, size);\n+\tfree(buf);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318523","messageId":"8cc59c706934134294e91a99062f7dcc0bda17db.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 12/25] split_commit_in_progress(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:05Z","receivedAt":"2017-05-02T16:02:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 7 ++++++-\n 1 file changed, 6 insertions(+), 1 deletion(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 0a6e16dbe0f..1f3f6bcb980 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status *s)\n \tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n \n \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n-\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n+\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n+\t\tfree(head);\n+\t\tfree(orig_head);\n+\t\tfree(rebase_amend);\n+\t\tfree(rebase_orig_head);\n \t\treturn split_in_progress;\n+\t}\n \n \tif (!strcmp(rebase_amend, rebase_orig_head)) {\n \t\tif (strcmp(head, rebase_amend))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318524","messageId":"7a78e949226251174c1b3a10b9a18addc2b52193.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 11/25] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:02Z","receivedAt":"2017-05-02T16:02:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change addresses part of the NEEDSWORK comment above the code,\ntherefore the comment needs to be adjusted, too.\n\nDiscovered via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/checkout.c | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex bfa5419f335..5faea3a05fa 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -235,14 +235,14 @@ static int checkout_merged(int pos, const struct checkout *state)\n \t/*\n \t * NEEDSWORK:\n \t * There is absolutely no reason to write this as a blob object\n-\t * and create a phony cache entry just to leak.  This hack is\n-\t * primarily to get to the write_entry() machinery that massages\n-\t * the contents to work-tree format and writes out which only\n-\t * allows it for a cache entry.  The code in write_entry() needs\n-\t * to be refactored to allow us to feed a <buffer, size, mode>\n-\t * instead of a cache entry.  Such a refactoring would help\n-\t * merge_recursive as well (it also writes the merge result to the\n-\t * object database even when it may contain conflicts).\n+\t * and create a phony cache entry.  This hack is primarily to get\n+\t * to the write_entry() machinery that massages the contents to\n+\t * work-tree format and writes out which only allows it for a\n+\t * cache entry.  The code in write_entry() needs to be refactored\n+\t * to allow us to feed a <buffer, size, mode> instead of a cache\n+\t * entry.  Such a refactoring would help merge_recursive as well\n+\t * (it also writes the merge result to the object database even\n+\t * when it may contain conflicts).\n \t */\n \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n \t\t\t    blob_type, oid.hash))\n@@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n \tif (!ce)\n \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n \tstatus = checkout_entry(ce, state, NULL);\n+\tfree(ce);\n \treturn status;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318525","messageId":"7b4d9dbb201ee3311e5e686d69ff158cc829f0c2.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 16/25] mktree: plug memory leaks reported by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:22Z","receivedAt":"2017-05-02T16:02:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mktree.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/mktree.c b/builtin/mktree.c\nindex de9b40fc63b..da0fd8cd706 100644\n--- a/builtin/mktree.c\n+++ b/builtin/mktree.c\n@@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \tunsigned mode;\n \tenum object_type mode_type; /* object type derived from mode */\n \tenum object_type obj_type; /* object type derived from sha */\n-\tchar *path;\n+\tchar *path, *to_free = NULL;\n \tunsigned char sha1[20];\n \n \tptr = buf;\n@@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t\tstruct strbuf p_uq = STRBUF_INIT;\n \t\tif (unquote_c_style(&p_uq, path, NULL))\n \t\t\tdie(\"invalid quoting\");\n-\t\tpath = strbuf_detach(&p_uq, NULL);\n+\t\tpath = to_free = strbuf_detach(&p_uq, NULL);\n \t}\n \n \t/*\n@@ -136,6 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t}\n \n \tappend_to_tree(mode, sha1, path);\n+\tfree(to_free);\n }\n \n int cmd_mktree(int ac, const char **av, const char *prefix)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318526","messageId":"e72c90ad8445eea72f8707d6780c1553d00ac263.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 13/25] setup_bare_git_dir(): help static analysis","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:08Z","receivedAt":"2017-05-02T16:02:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Coverity reported a memory leak in this function. However, it can only\nbe called once, as setup_git_directory() changes global state and hence\nis not reentrant.\n\nMark the variable as static to indicate that this is a singleton.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0309c278218..0320a9ad14c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n-\t\tconst char *gitdir;\n+\t\tstatic const char *gitdir;\n \n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318527","messageId":"afd43bcc0fe14498ce27cf776579aa931cd1be4c.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 15/25] pack-redundant: plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:19Z","receivedAt":"2017-05-02T16:02:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Identified via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/pack-redundant.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 72c815844dd..cb1df1c7614 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -442,6 +442,7 @@ static void minimize(struct pack_list **min)\n \t/* return if there are no objects missing from the unique set */\n \tif (missing->size == 0) {\n \t\t*min = unique;\n+\t\tfree(missing);\n \t\treturn;\n \t}\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318528","messageId":"06098b382225d6a8ef40b30717d86f1c750ab1ef.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 17/25] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:25Z","receivedAt":"2017-05-02T16:02:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by, you guessed it, Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/fast-export.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex e0220630d00..64617ad8e36 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -734,6 +734,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t\t\t     oid_to_hex(&tag->object.oid));\n \t\tcase DROP:\n \t\t\t/* Ignore this tag altogether */\n+\t\t\tfree(buf);\n \t\t\treturn;\n \t\tcase REWRITE:\n \t\t\tif (tagged->type != OBJ_COMMIT) {\n@@ -765,6 +766,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t       (int)(tagger_end - tagger), tagger,\n \t       tagger == tagger_end ? \"\" : \"\\n\",\n \t       (int)message_size, (int)message_size, message ? message : \"\");\n+\tfree(buf);\n }\n \n static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318529","messageId":"ab131705c4383dc408860b516b1e18b0753b0cbf.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 14/25] setup_discovered_git_dir(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:17Z","receivedAt":"2017-05-02T16:02:44Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The setup_explicit_git_dir() function does not take custody of the string\npassed as first parameter; we have to release it if we turned the value of\ngit_dir into an absolute path.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0320a9ad14c..e3f7699a902 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n+\t\tchar *to_free = NULL;\n+\t\tconst char *ret;\n+\n \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n-\t\t\tgitdir = real_pathdup(gitdir, 1);\n+\t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(\"Could not come back to cwd\");\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tfree(to_free);\n+\t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318530","messageId":"aab8cdfa2878f23b4d046d8303757031bb6ad0fb.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 18/25] receive-pack: plug memory leak in update()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:33Z","receivedAt":"2017-05-02T16:02:48Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/receive-pack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f96834f42c9..48c07ddb659 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -986,7 +986,8 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstatic char *namespaced_name;\n+\tconst char *ret;\n \tstruct object_id *old_oid = &cmd->old_oid;\n \tstruct object_id *new_oid = &cmd->new_oid;\n \n@@ -997,6 +998,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t}\n \n \tstrbuf_addf(&namespaced_name_buf, \"%s%s\", get_git_namespace(), name);\n+\tfree(namespaced_name);\n \tnamespaced_name = strbuf_detach(&namespaced_name_buf, NULL);\n \n \tif (is_ref_checked_out(namespaced_name)) {\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318531","messageId":"ba954872659d96aec305836b32a3adbb2c1c2a07.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 21/25] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:51Z","receivedAt":"2017-05-02T16:03:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"We free()d the `log` buffer when dwim_log() returned 1, but not when it\nreturned a larger value (which meant that it still allocated the buffer\nbut we simply ignored it).\n\nWhile in the vicinity, make sure that the `reflogs` structure as well as\nthe `branch` variable are released properly, too.\n\nIdentified by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n reflog-walk.c | 20 +++++++++++++++++---\n 1 file changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 99679f58255..c63eb1a3fd7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tif (!reflogs || reflogs->nr == 0) {\n \t\t\tstruct object_id oid;\n \t\t\tchar *b;\n-\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {\n+\t\t\tint ret = dwim_log(branch, strlen(branch),\n+\t\t\t\t\t   oid.hash, &b);\n+\t\t\tif (ret > 1)\n+\t\t\t\tfree(b);\n+\t\t\telse if (ret == 1) {\n \t\t\t\tif (reflogs) {\n \t\t\t\t\tfree(reflogs->ref);\n \t\t\t\t\tfree(reflogs);\n@@ -193,17 +197,27 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\t\t\treflogs = read_complete_reflog(branch);\n \t\t\t}\n \t\t}\n-\t\tif (!reflogs || reflogs->nr == 0)\n+\t\tif (!reflogs || reflogs->nr == 0) {\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n+\t\t\tfree(branch);\n \t\t\treturn -1;\n+\t\t}\n \t\tstring_list_insert(&info->complete_reflogs, branch)->util\n \t\t\t= reflogs;\n \t}\n+\tfree(branch);\n \n \tcommit_reflog = xcalloc(1, sizeof(struct commit_reflog));\n \tif (recno < 0) {\n \t\tcommit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);\n \t\tif (commit_reflog->recno < 0) {\n-\t\t\tfree(branch);\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n \t\t\tfree(commit_reflog);\n \t\t\treturn -1;\n \t\t}\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318532","messageId":"359c39c36a234c318b46ff934baa3757fdfc361d.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 22/25] remote: plug memory leak in match_explicit()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:54Z","receivedAt":"2017-05-02T16:03:08Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The `guess_ref()` returns an allocated buffer of which `make_linked_ref()`\ndoes not take custody (`alloc_ref()` makes a copy), therefore we need to\nrelease the buffer afterwards.\n\nNoticed via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n remote.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 801137c72eb..72b4591b983 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1191,9 +1191,10 @@ static int match_explicit(struct ref *src, struct ref *dst,\n \t\telse if (is_null_oid(&matched_src->new_oid))\n \t\t\terror(\"unable to delete '%s': remote ref does not exist\",\n \t\t\t      dst_value);\n-\t\telse if ((dst_guess = guess_ref(dst_value, matched_src)))\n+\t\telse if ((dst_guess = guess_ref(dst_value, matched_src))) {\n \t\t\tmatched_dst = make_linked_ref(dst_guess, dst_tail);\n-\t\telse\n+\t\t\tfree(dst_guess);\n+\t\t} else\n \t\t\terror(\"unable to push to unqualified destination: %s\\n\"\n \t\t\t      \"The destination refspec neither matches an \"\n \t\t\t      \"existing ref on the remote nor\\n\"\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318533","messageId":"0e2c75882e0c1a616ffbffffaa628b4fc27b87a4.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 20/25] shallow: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:47Z","receivedAt":"2017-05-02T16:03:13Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n shallow.c | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/shallow.c b/shallow.c\nindex 25b6db989bf..f9370961f99 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -473,11 +473,15 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1,\n \tstruct commit_list *head = NULL;\n \tint bitmap_nr = (info->nr_bits + 31) / 32;\n \tsize_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);\n-\tuint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */\n-\tuint32_t *bitmap = paint_alloc(info);\n \tstruct commit *c = lookup_commit_reference_gently(sha1, 1);\n+\tuint32_t *tmp; /* to be freed before return */\n+\tuint32_t *bitmap;\n+\n \tif (!c)\n \t\treturn;\n+\n+\ttmp = xmalloc(bitmap_size);\n+\tbitmap = paint_alloc(info);\n \tmemset(bitmap, 0, bitmap_size);\n \tbitmap[id / 32] |= (1U << (id % 32));\n \tcommit_list_insert(c, &head);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318534","messageId":"e0a836073648c9ea2cc1784d61780b806a81dfc0.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 19/25] line-log: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:35Z","receivedAt":"2017-05-02T16:03:23Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n line-log.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/line-log.c b/line-log.c\nindex a23b910471b..b9087814b8c 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n \tchanged = process_all_files(&parent_range, rev, &queue, range);\n \tif (parent)\n \t\tadd_line_range(rev, parent, parent_range);\n+\tfree_line_log_data(parent_range);\n \treturn changed;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318535","messageId":"ca9a9f22ffaebd6f59bdbe45fd6cc719d92b8d52.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 24/25] show_worktree(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:03:04Z","receivedAt":"2017-05-02T16:03:24Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The buffer allocated by shorten_unambiguous_ref() needs to be released.\n\nDiscovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/worktree.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 1722a9bdc2a..ff5dfd2b102 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -414,9 +414,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)\n \t\t\t\tfind_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));\n \t\tif (wt->is_detached)\n \t\t\tstrbuf_addstr(&sb, \"(detached HEAD)\");\n-\t\telse if (wt->head_ref)\n-\t\t\tstrbuf_addf(&sb, \"[%s]\", shorten_unambiguous_ref(wt->head_ref, 0));\n-\t\telse\n+\t\telse if (wt->head_ref) {\n+\t\t\tchar *ref = shorten_unambiguous_ref(wt->head_ref, 0);\n+\t\t\tstrbuf_addf(&sb, \"[%s]\", ref);\n+\t\t\tfree(ref);\n+\t\t} else\n \t\t\tstrbuf_addstr(&sb, \"(error)\");\n \t}\n \tprintf(\"%s\\n\", sb.buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318536","messageId":"d2e7c5e84c7f4dcdafe7fc135d2aa673deb3e112.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 25/25] submodule_uses_worktrees(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:03:07Z","receivedAt":"2017-05-02T16:03:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"There is really no reason why we would need to hold onto the allocated\nstring longer than necessary.\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n worktree.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/worktree.c b/worktree.c\nindex bae787cf8d7..89a81b13de3 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -399,6 +399,7 @@ int submodule_uses_worktrees(const char *path)\n \n \t/* The env would be set for the superproject. */\n \tget_common_dir_noenv(&sb, submodule_gitdir);\n+\tfree(submodule_gitdir);\n \n \t/*\n \t * The check below is only known to be good for repository format\n@@ -418,7 +419,6 @@ int submodule_uses_worktrees(const char *path)\n \t/* See if there is any file inside the worktrees directory. */\n \tdir = opendir(sb.buf);\n \tstrbuf_release(&sb);\n-\tfree(submodule_gitdir);\n \n \tif (!dir)\n \t\treturn 0;\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318537","messageId":"c3f8b61f789912213444364043bdef20cff970e1.1493740497.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v3 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-02T16:02:56Z","receivedAt":"2017-05-02T16:03:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When the `name_rev()` function is asked to dereference the tip name, it\nallocates memory. But when it turns out that another tip already\ndescribed the commit better than the current one, we forgot to release\nthe memory.\n\nPointed out by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/name-rev.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 92a5d8a5d26..e7a3fe7ee70 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n \tstruct rev_name *name = (struct rev_name *)commit->util;\n \tstruct commit_list *parents;\n \tint parent_number = 1;\n+\tchar *to_free = NULL;\n \n \tparse_commit(commit);\n \n@@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n \t\treturn;\n \n \tif (deref) {\n-\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n+\t\ttip_name = to_free = xstrfmt(\"%s^0\", tip_name);\n \n \t\tif (generation)\n \t\t\tdie(\"generation: %d, but deref?\", generation);\n@@ -53,8 +54,10 @@ static void name_rev(struct commit *commit,\n \t\tname->taggerdate = taggerdate;\n \t\tname->generation = generation;\n \t\tname->distance = distance;\n-\t} else\n+\t} else {\n+\t\tfree(to_free);\n \t\treturn;\n+\t}\n \n \tfor (parents = commit->parents;\n \t\t\tparents;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318543","messageId":"CAGZ79kbsy1qh02WjX0nt6ci4r+5DVxJcPzwburBf0TP0qaEMTA@mail.gmail.com","threadId":"45809","inReplyTo":"ab131705c4383dc408860b516b1e18b0753b0cbf.1493740497.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v3 14/25] setup_discovered_git_dir(): plug memory leak","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-05-02T17:20:29Z","receivedAt":"2017-05-02T17:20:39Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, May 2, 2017 at 9:02 AM, Johannes Schindelin\n<johannes.schindelin@gmx.de> wrote:\n> The setup_explicit_git_dir() function does not take custody of the string\n> passed as first parameter; we have to release it if we turned the value of\n> git_dir into an absolute path.\n>\n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>  setup.c | 9 +++++++--\n>  1 file changed, 7 insertions(+), 2 deletions(-)\n>\n> diff --git a/setup.c b/setup.c\n> index 0320a9ad14c..e3f7699a902 100644\n> --- a/setup.c\n> +++ b/setup.c\n> @@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n>\n>         /* --work-tree is set without --git-dir; use discovered one */\n>         if (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n> +               char *to_free = NULL;\n> +               const char *ret;\n> +\n>                 if (offset != cwd->len && !is_absolute_path(gitdir))\n> -                       gitdir = real_pathdup(gitdir, 1);\n> +                       gitdir = to_free = real_pathdup(gitdir, 1);\n>                 if (chdir(cwd->buf))\n>                         die_errno(\"Could not come back to cwd\");\n\nAs the original motivation was to shut up Coverity, this may not\naccomplish that goal, as in the path of taking the die_errno, we do not\nfree `to_free`. But that is ok as the actual goal is to hav no memleaks\nin the good case. A memleak just before a die is no big deal.\n\n> -               return setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n> +               ret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n> +               free(to_free);\n> +               return ret;\n\nAnd we free our pathdup from above, makes sense.\n\nThanks,\nStefan\n"},{"id":"318552","messageId":"20170502181511.wxr75p2uuwc4nni2@sigill.intra.peff.net","threadId":"45809","inReplyTo":"CAGZ79kbsy1qh02WjX0nt6ci4r+5DVxJcPzwburBf0TP0qaEMTA@mail.gmail.com","subject":"Re: [PATCH v3 14/25] setup_discovered_git_dir(): plug memory leak","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2017-05-02T18:15:11Z","receivedAt":"2017-05-02T18:15:19Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Tue, May 02, 2017 at 10:20:29AM -0700, Stefan Beller wrote:\n\n> > -                       gitdir = real_pathdup(gitdir, 1);\n> > +                       gitdir = to_free = real_pathdup(gitdir, 1);\n> >                 if (chdir(cwd->buf))\n> >                         die_errno(\"Could not come back to cwd\");\n> \n> As the original motivation was to shut up Coverity, this may not\n> accomplish that goal, as in the path of taking the die_errno, we do not\n> free `to_free`. But that is ok as the actual goal is to hav no memleaks\n> in the good case. A memleak just before a die is no big deal.\n\nI think Coverity understands our NORETURN attributes, so this should be\nfine (and if it doesn't, then we should fix that in the model file; but\nfrom the general results I've seen, it does).\n\n-Peff\n"},{"id":"318611","messageId":"alpine.DEB.2.20.1705031134250.3480@virtualbox","threadId":"45809","inReplyTo":"20170502181511.wxr75p2uuwc4nni2@sigill.intra.peff.net","subject":"Re: [PATCH v3 14/25] setup_discovered_git_dir(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-03T09:35:56Z","receivedAt":"2017-05-03T09:36:28Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Peff,\n\nOn Tue, 2 May 2017, Jeff King wrote:\n\n> On Tue, May 02, 2017 at 10:20:29AM -0700, Stefan Beller wrote:\n> \n> > > -                       gitdir = real_pathdup(gitdir, 1);\n> > > +                       gitdir = to_free = real_pathdup(gitdir, 1);\n> > >                 if (chdir(cwd->buf))\n> > >                         die_errno(\"Could not come back to cwd\");\n> > \n> > As the original motivation was to shut up Coverity, this may not\n> > accomplish that goal, as in the path of taking the die_errno, we do not\n> > free `to_free`. But that is ok as the actual goal is to hav no memleaks\n> > in the good case. A memleak just before a die is no big deal.\n> \n> I think Coverity understands our NORETURN attributes, so this should be\n> fine (and if it doesn't, then we should fix that in the model file; but\n> from the general results I've seen, it does).\n\nThat matches my impression.\n\nNote that Coverity cannot figure out that all of our cmd_*() functions are\ncalled in code paths that exit() with their return value. Otherwise we\nwould not see reports about those tons of intentional \"let's abuse exit()\nas our garbage collector\" instances.\n\nCiao,\nDscho\n"},{"id":"318693","messageId":"789a242b-7369-f24c-0b92-09f415f9fcb5@web.de","threadId":"45809","inReplyTo":"10fc0a4a37b4167f49c967ece08f531cb1e8d6b1.1493740497.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v3 01/25] mingw: avoid memory leak when splitting PATH","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2017-05-03T19:48:42Z","receivedAt":"2017-05-03T19:48:55Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.05.2017 um 18:00 schrieb Johannes Schindelin:\n> In the (admittedly, concocted) case that PATH consists only of colons, we\n> would leak the duplicated string.\n\nNit: It's about semicolons, right?  At least that's what get_path_split\nis searching for.  Or is there some kind of translation going on?\n\nRené\n"},{"id":"318694","messageId":"243bb3c1-d01f-f5e5-544e-2ece2a4e5844@web.de","threadId":"45809","inReplyTo":"758b5a5dbe83832db7362246127b8bd1ca7beb9f.1493740497.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v3 02/25] winansi: avoid use of uninitialized value","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2017-05-03T19:48:39Z","receivedAt":"2017-05-03T19:49:07Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.05.2017 um 18:01 schrieb Johannes Schindelin:\n> When stdout is not connected to a Win32 console, we incorrectly used an\n> uninitialized value for the \"plain\" character attributes.\n> \n> Detected by Coverity.\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>   compat/winansi.c | 2 ++\n>   1 file changed, 2 insertions(+)\n> \n> diff --git a/compat/winansi.c b/compat/winansi.c\n> index 793420f9d0d..fd6910746c8 100644\n> --- a/compat/winansi.c\n> +++ b/compat/winansi.c\n> @@ -105,6 +105,8 @@ static int is_console(int fd)\n>   \tif (!fd) {\n>   \t\tif (!GetConsoleMode(hcon, &mode))\n>   \t\t\treturn 0;\n> +\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n> +\t\t\tFOREGROUND_RED;\n>   \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n>   \t\treturn 0;\n>   \n\nSo is_console is called with fd being 1 (stdout), 2 (stderr) and 0\n(stdin), in that order.  If the first two calls abort early for some\nreason we may end up here.  The added code is for white text on black\nbackground.  An alias for that combination, FOREGROUND_ALL, is defined\na few lines down; for a minimal fix it's not worth moving it up.  attr\nand plain_attr are both initialized to sbi.wAttributes.\n\nThat as a bit more complicated than it looked initially.  The order of\ncalls is important, \"stdout\" in the commit message includes stderr as\nwell and it doesn't just affect plain_attr.\n\nWould a value of 0 (black text on black background) suffice if only\nstdin is connected to a console?  Colors don't matter if there is\nnothing to see, right?\n\nAnyway, the change makes sense as is, but it took me a while to get it.\n\nRené\n"},{"id":"318700","messageId":"8a0a2230-239e-b6c8-f7c0-8192e6cec7ec@web.de","threadId":"45809","inReplyTo":"8cc59c706934134294e91a99062f7dcc0bda17db.1493740497.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v3 12/25] split_commit_in_progress(): fix memory leak","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2017-05-03T20:59:03Z","receivedAt":"2017-05-03T20:59:37Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 02.05.2017 um 18:02 schrieb Johannes Schindelin:\n> Reported via Coverity.\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>   wt-status.c | 7 ++++++-\n>   1 file changed, 6 insertions(+), 1 deletion(-)\n> \n> diff --git a/wt-status.c b/wt-status.c\n> index 0a6e16dbe0f..1f3f6bcb980 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status *s)\n>   \tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n>   \n>   \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n> -\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n> +\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n> +\t\tfree(head);\n> +\t\tfree(orig_head);\n> +\t\tfree(rebase_amend);\n> +\t\tfree(rebase_orig_head);\n>   \t\treturn split_in_progress;\n> +\t}\n>   \n>   \tif (!strcmp(rebase_amend, rebase_orig_head)) {\n>   \t\tif (strcmp(head, rebase_amend))\n> \n\nThe return line could be replaced by \"; else\" to achieve the same\nresult, without duplicating the free calls.\n\nRené\n"},{"id":"318720","messageId":"xmqq60hhb69x.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1705021433060.3480@virtualbox","subject":"Re: [PATCH v2 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-04T04:22:18Z","receivedAt":"2017-05-04T04:22:35Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Hi Junio,\n>\n> On Mon, 1 May 2017, Junio C Hamano wrote:\n>\n>> Junio C Hamano <gitster@pobox.com> writes:\n>> \n>> > Johannes Schindelin <johannes.schindelin@gmx.de> writes:\n>> >\n>> >> diff --git a/builtin/name-rev.c b/builtin/name-rev.c\n>> >> index 92a5d8a5d26..a4ce73fb1e9 100644\n>> >> --- a/builtin/name-rev.c\n>> >> +++ b/builtin/name-rev.c\n>> >> @@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n>> >>  \tstruct rev_name *name = (struct rev_name *)commit->util;\n>> >>  \tstruct commit_list *parents;\n>> >>  \tint parent_number = 1;\n>> >> +\tchar *p = NULL;\n>> >>  \n>> >>  \tparse_commit(commit);\n>> >>  \n>> >> @@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n>> >>  \t\treturn;\n>> >>  \n>> >>  \tif (deref) {\n>> >> -\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n>> >> +\t\ttip_name = p = xstrfmt(\"%s^0\", tip_name);\n>> \n>> I'll rename 'p' to 'to_free' while queuing, though.  Without a\n>> descriptive name, it was confusing to view while resolving conflicts\n>> with another in-flight topic.\n>\n> Good point. I also used `p` in builtin/mktree.c and setup.c. While you\n> seem to have renamed it in builtin/mktree.c, I think setup.c also needs\n> the same fixup.\n\nYes, no question about it. I just left it as-is as I saw it is\nlikely to be rerolled anyway due to other issues ;-)\n"},{"id":"318752","messageId":"alpine.DEB.2.21.1.1705041206030.4905@virtualbox","threadId":"45809","inReplyTo":"243bb3c1-d01f-f5e5-544e-2ece2a4e5844@web.de","subject":"Re: [PATCH v3 02/25] winansi: avoid use of uninitialized value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T10:23:56Z","receivedAt":"2017-05-04T10:24:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi René,\n\nOn Wed, 3 May 2017, René Scharfe wrote:\n\n> Am 02.05.2017 um 18:01 schrieb Johannes Schindelin:\n> > \n> > diff --git a/compat/winansi.c b/compat/winansi.c\n> > index 793420f9d0d..fd6910746c8 100644\n> > --- a/compat/winansi.c\n> > +++ b/compat/winansi.c\n> > @@ -105,6 +105,8 @@ static int is_console(int fd)\n> >    if (!fd) {\n> >     if (!GetConsoleMode(hcon, &mode))\n> >   \t\t\treturn 0;\n> > +\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n> > +\t\t\tFOREGROUND_RED;\n> >    } else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n> >     return 0;\n> >   \n> \n> So is_console is called with fd being 1 (stdout), 2 (stderr) and 0\n> (stdin), in that order.\n\nCorrect. I guess this is the important part missing from the commit\nmessage.\n\nOh, I also saw that I talked about stdout in the commit message, but !fd\ntests for stdin!\n\n> If the first two calls abort early for some reason we may end up here.\n\nYep. \"some reason\" being: there is no console attached to stdout nor\nstderr.\n\n> The added code is for white text on black background.  An alias for that\n> combination, FOREGROUND_ALL, is defined a few lines down; for a minimal\n> fix it's not worth moving it up.  attr and plain_attr are both\n> initialized to sbi.wAttributes.\n\nExactly.\n\n> That as a bit more complicated than it looked initially.  The order of\n> calls is important, \"stdout\" in the commit message includes stderr as\n> well and it doesn't just affect plain_attr.\n\nRight, it also affects the \"current\" attributes.\n\n> Would a value of 0 (black text on black background) suffice if only\n> stdin is connected to a console?  Colors don't matter if there is\n> nothing to see, right?\n\nI think that would make it both easier to understand the patch and to\ncatch regressions in case anybody feels the order of the is_console()\ncalls should be changed...\n\nThis is my current squash! commit (the original commit message will be\nreplaced by the commit message body of this commit):\n\n-- snipsnap --\nSubject: [PATCH] squash! winansi: avoid use of uninitialized value\n\nwinansi: avoid use of uninitialized value\n\nTo initialize the foreground color attributes of \"plain text\", our ANSI\nemulation tries to infer them from the currently attached console while\nrunning the is_console() function. This function first tries to detect any\nconsole attached to stdout, then it is called with stderr.\n\nIf neither stdout nor stderr has any console attached, it does not\nactually matter what we use for \"plain text\" attributes, as we never need\nto output any text to any console in that case.\n\nHowever, after working on stdout and stderr, is_console() is called with\nstdin, and it still tries to initialize the \"plain text\" attributes if\nthey had not been initialized earlier. In this case, we cannot detect any\nattributes, and we used an uninitialized value for them.\n\nNaturally, Coverity complained about this use case because it could not\nreason about the code deeply enough to figure out that we do not even use\nthose attributes in that case.\n\nLet's just initialize the value to 0 in that case, both to avoid future\nCoverity reports, and to help catch future regressions in case anybody\nchanges the order of the is_console() calls (which would make the text\nblack on black).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex 861b79d8c31..a11a0f16d27 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -105,8 +105,13 @@ static int is_console(int fd)\n \tif (!fd) {\n \t\tif (!GetConsoleMode(hcon, &mode))\n \t\t\treturn 0;\n-\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n-\t\t\tFOREGROUND_RED;\n+\t\t/*\n+\t\t * This code path is only reached if there is no console\n+\t\t * attached to stdout/stderr, i.e. we will not need to output\n+\t\t * any text to any console, therefore we might just as well\n+\t\t * use black as foreground color.\n+\t\t */\n+\t\tsbi.wAttributes = 0;\n \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n \t\treturn 0;\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318754","messageId":"alpine.DEB.2.21.1.1705041225090.4905@virtualbox","threadId":"45809","inReplyTo":"789a242b-7369-f24c-0b92-09f415f9fcb5@web.de","subject":"Re: [PATCH v3 01/25] mingw: avoid memory leak when splitting PATH","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T10:29:33Z","receivedAt":"2017-05-04T10:29:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi René,\n\nOn Wed, 3 May 2017, René Scharfe wrote:\n\n> Am 02.05.2017 um 18:00 schrieb Johannes Schindelin:\n> > In the (admittedly, concocted) case that PATH consists only of colons, we\n> > would leak the duplicated string.\n> \n> Nit: It's about semicolons, right?  At least that's what get_path_split\n> is searching for.  Or is there some kind of translation going on?\n\nTrue, it is semicolons.\n\nI'll reword the commit message to actually use `path delimiters`, to make\nit more understandable to the Unix folk (who would most likely be puzzled\nthat PATH is separated by semicolons).\n\nThanks,\nDscho"},{"id":"318755","messageId":"alpine.DEB.2.21.1.1705041231270.4905@virtualbox","threadId":"45809","inReplyTo":"8a0a2230-239e-b6c8-f7c0-8192e6cec7ec@web.de","subject":"Re: [PATCH v3 12/25] split_commit_in_progress(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T10:59:19Z","receivedAt":"2017-05-04T10:59:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi René,\n\nOn Wed, 3 May 2017, René Scharfe wrote:\n\n> Am 02.05.2017 um 18:02 schrieb Johannes Schindelin:\n> > Reported via Coverity.\n> > \n> > Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> > ---\n> >   wt-status.c | 7 ++++++-\n> >   1 file changed, 6 insertions(+), 1 deletion(-)\n> > \n> > diff --git a/wt-status.c b/wt-status.c\n> > index 0a6e16dbe0f..1f3f6bcb980 100644\n> > --- a/wt-status.c\n> > +++ b/wt-status.c\n> > @@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status\n> > *s)\n> >    char *rebase_orig_head =\n> >    read_line_from_git_path(\"rebase-merge/orig-head\");\n> >   \n> >   \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n> > -\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n> > +\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n> > +\t\tfree(head);\n> > +\t\tfree(orig_head);\n> > +\t\tfree(rebase_amend);\n> > +\t\tfree(rebase_orig_head);\n> >   \t\treturn split_in_progress;\n> > +\t}\n> >   \n> >    if (!strcmp(rebase_amend, rebase_orig_head)) {\n> >     if (strcmp(head, rebase_amend))\n> > \n> \n> The return line could be replaced by \"; else\" to achieve the same\n> result, without duplicating the free calls.\n\nTrue. It is much harder to explain it that way, though: the context looks\nlike this:\n\nstatic int split_commit_in_progress(struct wt_status *s)\n {\n        int split_in_progress = 0;\n        char *head = read_line_from_git_path(\"HEAD\");\n        char *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n        char *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n        char *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n\n        if (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n-           !s->branch || strcmp(s->branch, \"HEAD\"))\n+           !s->branch || strcmp(s->branch, \"HEAD\")) {\n+               free(head);\n+               free(orig_head);\n+               free(rebase_amend);\n+               free(rebase_orig_head);\n                return split_in_progress;\n+       }\n\n        if (!strcmp(rebase_amend, rebase_orig_head)) {\n                if (strcmp(head, rebase_amend))\n                        split_in_progress = 1;\n        } else if (strcmp(orig_head, rebase_orig_head)) {\n                split_in_progress = 1;\n        }\n\n        if (!s->amend && !s->nowarn && !s->workdir_dirty)\n                split_in_progress = 0;\n\n        free(head);\n        free(orig_head);\n        free(rebase_amend);\n        free(rebase_orig_head);\n        return split_in_progress;\n }\n\nSo as you see, if we make the change you suggested, the next if() is hit\nwhich possibly sets split_in_progress = 0.\n\nThe thing is: this variable has been initialized to 0 in the beginning! So\nthis conditional assignment would be a noop, unless any of the code paths\nbefore this conditional modified split_in_progress.\n\nAfter you fully wrapped your head around this code, I am sure you agree\nthat the code is unnecessarily confusing to begin with: why do we go out\nof our way to allocate and read all those strings, compare them to figure\nout whether there is a split in progress, just to look at bits in the\nwt_status struct (that we had available from the beginning) to potentially\nundo all of that.\n\nWhat's worse, I cannot even find a logical explanation why the code is so\nconfusing, as it has been added as it is today in commit 2d1ccebae41\n(status: better advices when splitting a commit (during rebase -i),\n2012-06-10).\n\nSo I think this function really wants to be fixed more fully (although I\nfeel bad for inserting such a non-trivial fix into a patch series\notherwise populated by trivial memory/resource leak plugs):\n\n-- snipsnap --\nSubject: [PATCH] squash! split_commit_in_progress(): fix memory leak\n\nsplit_commit_in_progress(): simplify & fix memory leak\n\nThis function did a whole lot of unnecessary work, such as reading in\nfour files just to figure out that, oh, hey, we do not need to look at\nthem after all because the HEAD is not detached.\n\nSimplify the entire function to return early when possible, to read in\nthe files only when necessary, and to release the allocated memory\nalways (there was a leak, reported via Coverity, where we failed to\nrelease the allocated strings if the HEAD is not detached).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 39 +++++++++++++++++----------------------\n 1 file changed, 17 insertions(+), 22 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 1f3f6bcb980..117ac8cfb01 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1082,34 +1082,29 @@ static char *read_line_from_git_path(const char *filename)\n static int split_commit_in_progress(struct wt_status *s)\n {\n \tint split_in_progress = 0;\n-\tchar *head = read_line_from_git_path(\"HEAD\");\n-\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n-\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n-\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n-\n-\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n-\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n-\t\tfree(head);\n-\t\tfree(orig_head);\n-\t\tfree(rebase_amend);\n-\t\tfree(rebase_orig_head);\n-\t\treturn split_in_progress;\n-\t}\n-\n-\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n-\t\tif (strcmp(head, rebase_amend))\n-\t\t\tsplit_in_progress = 1;\n-\t} else if (strcmp(orig_head, rebase_orig_head)) {\n-\t\tsplit_in_progress = 1;\n-\t}\n+\tchar *head, *orig_head, *rebase_amend, *rebase_orig_head;\n+\n+\tif ((!s->amend && !s->nowarn && !s->workdir_dirty) ||\n+\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n+\t\treturn 0;\n \n-\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n-\t\tsplit_in_progress = 0;\n+\thead = read_line_from_git_path(\"HEAD\");\n+\torig_head = read_line_from_git_path(\"ORIG_HEAD\");\n+\trebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n+\trebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n+\n+\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head)\n+\t\t; /* fall through, no split in progress */\n+\telse if (!strcmp(rebase_amend, rebase_orig_head))\n+\t\tsplit_in_progress = !!strcmp(head, rebase_amend);\n+\telse if (strcmp(orig_head, rebase_orig_head))\n+\t\tsplit_in_progress = 1;\n \n \tfree(head);\n \tfree(orig_head);\n \tfree(rebase_amend);\n \tfree(rebase_orig_head);\n+\n \treturn split_in_progress;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318761","messageId":"c20dfea3a2cbf5905d52d5a550653736dd71ea4c.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 04/25] add_commit_patch_id(): avoid allocating memory unnecessarily","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:38Z","receivedAt":"2017-05-04T13:56:01Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"It would appear that we allocate (and forget to release) memory if the\npatch ID is not even defined.\n\nReported by the Coverity tool.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n patch-ids.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/patch-ids.c b/patch-ids.c\nindex fa8f11de826..92eba7a059e 100644\n--- a/patch-ids.c\n+++ b/patch-ids.c\n@@ -99,11 +99,12 @@ struct patch_id *has_commit_patch_id(struct commit *commit,\n struct patch_id *add_commit_patch_id(struct commit *commit,\n \t\t\t\t     struct patch_ids *ids)\n {\n-\tstruct patch_id *key = xcalloc(1, sizeof(*key));\n+\tstruct patch_id *key;\n \n \tif (!patch_id_defined(commit))\n \t\treturn NULL;\n \n+\tkey = xcalloc(1, sizeof(*key));\n \tif (init_patch_id_entry(key, commit, ids)) {\n \t\tfree(key);\n \t\treturn NULL;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318762","messageId":"c11fc0730bff65d15566ead2334f9172f1849c4f.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 07/25] difftool: address a couple of resource/memory leaks","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:48Z","receivedAt":"2017-05-04T13:56:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change plugs a couple of memory leaks and makes sure that the file\ndescriptor is closed in run_dir_diff().\n\nSpotted by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/difftool.c | 33 +++++++++++++++++++++++----------\n 1 file changed, 23 insertions(+), 10 deletions(-)\n\ndiff --git a/builtin/difftool.c b/builtin/difftool.c\nindex 1354d0e4625..b9a892f2693 100644\n--- a/builtin/difftool.c\n+++ b/builtin/difftool.c\n@@ -226,6 +226,7 @@ static void changed_files(struct hashmap *result, const char *index_path,\n \t\thashmap_entry_init(entry, strhash(buf.buf));\n \t\thashmap_add(result, entry);\n \t}\n+\tfclose(fp);\n \tif (finish_command(&diff_files))\n \t\tdie(\"diff-files did not exit properly\");\n \tstrbuf_release(&index_env);\n@@ -439,8 +440,10 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \n \t\tif (lmode && status != 'C') {\n-\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate))\n-\t\t\t\treturn error(\"could not write '%s'\", src_path);\n+\t\t\tif (checkout_path(lmode, &loid, src_path, &lstate)) {\n+\t\t\t\tret = error(\"could not write '%s'\", src_path);\n+\t\t\t\tgoto finish;\n+\t\t\t}\n \t\t}\n \n \t\tif (rmode && !S_ISLNK(rmode)) {\n@@ -456,9 +459,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\thashmap_add(&working_tree_dups, entry);\n \n \t\t\tif (!use_wt_file(workdir, dst_path, &roid)) {\n-\t\t\t\tif (checkout_path(rmode, &roid, dst_path, &rstate))\n-\t\t\t\t\treturn error(\"could not write '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (checkout_path(rmode, &roid, dst_path,\n+\t\t\t\t\t\t  &rstate)) {\n+\t\t\t\t\tret = error(\"could not write '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t} else if (!is_null_oid(&roid)) {\n \t\t\t\t/*\n \t\t\t\t * Changes in the working tree need special\n@@ -473,10 +479,12 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t\t\t\t\tADD_CACHE_JUST_APPEND);\n \n \t\t\t\tadd_path(&rdir, rdir_len, dst_path);\n-\t\t\t\tif (ensure_leading_directories(rdir.buf))\n-\t\t\t\t\treturn error(\"could not create \"\n-\t\t\t\t\t\t     \"directory for '%s'\",\n-\t\t\t\t\t\t     dst_path);\n+\t\t\t\tif (ensure_leading_directories(rdir.buf)) {\n+\t\t\t\t\tret = error(\"could not create \"\n+\t\t\t\t\t\t    \"directory for '%s'\",\n+\t\t\t\t\t\t    dst_path);\n+\t\t\t\t\tgoto finish;\n+\t\t\t\t}\n \t\t\t\tadd_path(&wtdir, wtdir_len, dst_path);\n \t\t\t\tif (symlinks) {\n \t\t\t\t\tif (symlink(wtdir.buf, rdir.buf)) {\n@@ -497,13 +505,15 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\t}\n \t}\n \n+\tfclose(fp);\n+\tfp = NULL;\n \tif (finish_command(&child)) {\n \t\tret = error(\"error occurred running diff --raw\");\n \t\tgoto finish;\n \t}\n \n \tif (!i)\n-\t\treturn 0;\n+\t\tgoto finish;\n \n \t/*\n \t * Changes to submodules require special treatment.This loop writes a\n@@ -626,6 +636,9 @@ static int run_dir_diff(const char *extcmd, int symlinks, const char *prefix,\n \t\texit_cleanup(tmpdir, rc);\n \n finish:\n+\tif (fp)\n+\t\tfclose(fp);\n+\n \tfree(lbase_dir);\n \tfree(rbase_dir);\n \tstrbuf_release(&ldir);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318763","messageId":"e05ac6ff3315ad809682dafa7e4542e223df8bf5.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 06/25] get_mail_commit_oid(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:45Z","receivedAt":"2017-05-04T13:56:06Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we fail to read, or parse, the file, we still want to close the file\ndescriptor and release the strbuf.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/am.c | 15 ++++++---------\n 1 file changed, 6 insertions(+), 9 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex a95dd8b4e6c..9c5c2c778e2 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -1351,19 +1351,16 @@ static int get_mail_commit_oid(struct object_id *commit_id, const char *mail)\n \tstruct strbuf sb = STRBUF_INIT;\n \tFILE *fp = xfopen(mail, \"r\");\n \tconst char *x;\n+\tint ret = 0;\n \n-\tif (strbuf_getline_lf(&sb, fp))\n-\t\treturn -1;\n-\n-\tif (!skip_prefix(sb.buf, \"From \", &x))\n-\t\treturn -1;\n-\n-\tif (get_oid_hex(x, commit_id) < 0)\n-\t\treturn -1;\n+\tif (strbuf_getline_lf(&sb, fp) ||\n+\t    !skip_prefix(sb.buf, \"From \", &x) ||\n+\t    get_oid_hex(x, commit_id) < 0)\n+\t\tret = -1;\n \n \tstrbuf_release(&sb);\n \tfclose(fp);\n-\treturn 0;\n+\treturn ret;\n }\n \n /**\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318764","messageId":"9f1b809e84b1f175d1c56e58c53c785faab79ae2.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 05/25] git_config_rename_section_in_file(): avoid resource leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:41Z","receivedAt":"2017-05-04T13:56:16Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In case of errors, we really want the file descriptor to be closed.\n\nDiscovered by a Coverity scan.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n config.c | 5 ++++-\n 1 file changed, 4 insertions(+), 1 deletion(-)\n\ndiff --git a/config.c b/config.c\nindex b4a3205da32..a30056ec7e9 100644\n--- a/config.c\n+++ b/config.c\n@@ -2621,7 +2621,7 @@ int git_config_rename_section_in_file(const char *config_filename,\n \tstruct lock_file *lock;\n \tint out_fd;\n \tchar buf[1024];\n-\tFILE *config_file;\n+\tFILE *config_file = NULL;\n \tstruct stat st;\n \n \tif (new_name && !section_name_is_ok(new_name)) {\n@@ -2703,11 +2703,14 @@ int git_config_rename_section_in_file(const char *config_filename,\n \t\t}\n \t}\n \tfclose(config_file);\n+\tconfig_file = NULL;\n commit_and_out:\n \tif (commit_lock_file(lock) < 0)\n \t\tret = error_errno(\"could not write config file %s\",\n \t\t\t\t  config_filename);\n out:\n+\tif (config_file)\n+\t\tfclose(config_file);\n \trollback_lock_file(lock);\n out_no_rollback:\n \tfree(filename_buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318765","messageId":"2f54cb32079186abea8ca12c3e81f3d993500673.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 09/25] mailinfo & mailsplit: check for EOF while parsing","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:14Z","receivedAt":"2017-05-04T13:56:26Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"While POSIX states that it is okay to pass EOF to isspace() (and it seems\nto be implied that EOF should *not* be treated as whitespace), and also to\npass EOF to ungetc() (which seems to be intended to fail without buffering\nthe character), it is much better to handle these cases explicitly. Not\nonly does it reduce head-scratching (and helps static analysis avoid\nreporting false positives), it also lets us handle files containing\nnothing but whitespace by erroring out.\n\nReported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mailsplit.c | 10 ++++++++++\n mailinfo.c          |  9 ++++++++-\n 2 files changed, 18 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/mailsplit.c b/builtin/mailsplit.c\nindex 30681681c13..664400b8169 100644\n--- a/builtin/mailsplit.c\n+++ b/builtin/mailsplit.c\n@@ -232,6 +232,16 @@ static int split_mbox(const char *file, const char *dir, int allow_bare,\n \n \tdo {\n \t\tpeek = fgetc(f);\n+\t\tif (peek == EOF) {\n+\t\t\tif (f == stdin)\n+\t\t\t\t/* empty stdin is OK */\n+\t\t\t\tret = skip;\n+\t\t\telse {\n+\t\t\t\tfclose(f);\n+\t\t\t\terror(_(\"empty mbox: '%s'\"), file);\n+\t\t\t}\n+\t\t\tgoto out;\n+\t\t}\n \t} while (isspace(peek));\n \tungetc(peek, f);\n \ndiff --git a/mailinfo.c b/mailinfo.c\nindex 68037758f2f..f92cb9f729c 100644\n--- a/mailinfo.c\n+++ b/mailinfo.c\n@@ -882,7 +882,10 @@ static int read_one_header_line(struct strbuf *line, FILE *in)\n \tfor (;;) {\n \t\tint peek;\n \n-\t\tpeek = fgetc(in); ungetc(peek, in);\n+\t\tpeek = fgetc(in);\n+\t\tif (peek == EOF)\n+\t\t\tbreak;\n+\t\tungetc(peek, in);\n \t\tif (peek != ' ' && peek != '\\t')\n \t\t\tbreak;\n \t\tif (strbuf_getline_lf(&continuation, in))\n@@ -1099,6 +1102,10 @@ int mailinfo(struct mailinfo *mi, const char *msg, const char *patch)\n \n \tdo {\n \t\tpeek = fgetc(mi->input);\n+\t\tif (peek == EOF) {\n+\t\t\tfclose(cmitmsg);\n+\t\t\treturn error(\"empty patch: '%s'\", patch);\n+\t\t}\n \t} while (isspace(peek));\n \tungetc(peek, mi->input);\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318766","messageId":"57f66d1a001329bac1ea4aa0c471ad5a359a632f.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 08/25] status: close file descriptor after reading git-rebase-todo","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:52Z","receivedAt":"2017-05-04T13:56:30Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 03754849626..0a6e16dbe0f 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1168,6 +1168,7 @@ static int read_rebase_todolist(const char *fname, struct string_list *lines)\n \t\tabbrev_sha1_in_line(&line);\n \t\tstring_list_append(lines, line.buf);\n \t}\n+\tfclose(f);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318767","messageId":"7e3a788caec040f9ec907969c01dc2bc7be4b490.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 02/25] winansi: avoid use of uninitialized value","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:29Z","receivedAt":"2017-05-04T13:56:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"To initialize the foreground color attributes of \"plain text\", our ANSI\nemulation tries to infer them from the currently attached console while\nrunning the is_console() function. This function first tries to detect any\nconsole attached to stdout, then it is called with stderr.\n\nIf neither stdout nor stderr has any console attached, it does not\nactually matter what we use for \"plain text\" attributes, as we never need\nto output any text to any console in that case.\n\nHowever, after working on stdout and stderr, is_console() is called with\nstdin, and it still tries to initialize the \"plain text\" attributes if\nthey had not been initialized earlier. In this case, we cannot detect any\nattributes, and we used an uninitialized value for them.\n\nNaturally, Coverity complained about this use case because it could not\nreason about the code deeply enough to figure out that we do not even use\nthose attributes in that case.\n\nLet's just initialize the value to 0 in that case, both to avoid future\nCoverity reports, and to help catch future regressions in case anybody\nchanges the order of the is_console() calls (which would make the text\nblack on black).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 7 +++++++\n 1 file changed, 7 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex 793420f9d0d..a551de90eb0 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -105,6 +105,13 @@ static int is_console(int fd)\n \tif (!fd) {\n \t\tif (!GetConsoleMode(hcon, &mode))\n \t\t\treturn 0;\n+\t\t/*\n+\t\t * This code path is only reached if there is no console\n+\t\t * attached to stdout/stderr, i.e. we will not need to output\n+\t\t * any text to any console, therefore we might just as well\n+\t\t * use black as foreground color.\n+\t\t */\n+\t\tsbi.wAttributes = 0;\n \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n \t\treturn 0;\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318768","messageId":"cover.1493906084.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493740497.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 00/25] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:54:56Z","receivedAt":"2017-05-04T13:56:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"I recently registered the git-for-windows fork with Coverity to ensure\nthat even the Windows-specific patches get some static analysis love.\n\nWhile at it, I squashed a couple of obvious issues in the part that is\nnot Windows-specific.\n\nNote: while this patch series squashes some of those issues, the\nremaining issues are not necessarily all false positives (e.g. Coverity\ngetting fooled by our FLEX_ARRAY trick into believing that the last\nmember of the struct is indeed a 0 or 1 size array) or intentional (e.g.\nbuiltins not releasing memory because exit() is called right after\nreturning from the function that leaks memory).\n\nNotable examples of the remaining issues are:\n\n- a couple of callers of shorten_unambiguous_ref() assume that they do\n  not have to release the memory returned from that function, often\n  assigning the pointer to a `const` variable that typically does not\n  hold a pointer that needs to be free()d. My hunch is that we will want\n  to convert that function to have a fixed number of static buffers and\n  use those in a round robin fashion à la sha1_to_hex().\n\n- pack-redundant.c seems to have hard-to-reason-about code paths that\n  may eventually leak memory. Essentially, the custody of the allocated\n  memory is not clear at all.\n\n- fast-import.c calls strbuf_detach() on the command_buf without any\n  obvious rationale. Turns out that *some* code paths assign\n  command_buf.buf to a `recent_command` which releases the buffer later.\n  However, from a cursory look it appears to me as if there are some\n  other code paths that skip that assignment, effectively causing a memory\n  leak once strbuf_detach() is called.\n\nSadly, I lack the time to pursue those remaining issues further.\n\nChanges since v3:\n\n- used 0 (black) for the foreground color attributes in winansi when we\n  have no console to print to, anyway.\n\n- clarified in the commit message when we hit the path, and why, where\n  we set the foreground color attributes to \"all black\".\n\n- reworded the commit message talking about splitting the PATH (on\n  Windows, it is delimited by semicolons, not colons, but it is even\n  better to just talk about the path delimiters because it does not\n  really happen which character is used, but it is important which role\n  it plays).\n\n- rewrote the split_commit_in_progress() function to have a more natural\n  flow while still fixing the memory leak.\n\n\nJohannes Schindelin (25):\n  mingw: avoid memory leak when splitting PATH\n  winansi: avoid use of uninitialized value\n  winansi: avoid buffer overrun\n  add_commit_patch_id(): avoid allocating memory unnecessarily\n  git_config_rename_section_in_file(): avoid resource leak\n  get_mail_commit_oid(): avoid resource leak\n  difftool: address a couple of resource/memory leaks\n  status: close file descriptor after reading git-rebase-todo\n  mailinfo & mailsplit: check for EOF while parsing\n  cat-file: fix memory leak\n  checkout: fix memory leak\n  split_commit_in_progress(): simplify & fix memory leak\n  setup_bare_git_dir(): help static analysis\n  setup_discovered_git_dir(): plug memory leak\n  pack-redundant: plug memory leak\n  mktree: plug memory leaks reported by Coverity\n  fast-export: avoid leaking memory in handle_tag()\n  receive-pack: plug memory leak in update()\n  line-log: avoid memory leak\n  shallow: avoid memory leak\n  add_reflog_for_walk: avoid memory leak\n  remote: plug memory leak in match_explicit()\n  name-rev: avoid leaking memory in the `deref` case\n  show_worktree(): plug memory leak\n  submodule_uses_worktrees(): plug memory leak\n\n builtin/am.c             | 15 ++++++---------\n builtin/cat-file.c       |  1 +\n builtin/checkout.c       | 17 +++++++++--------\n builtin/difftool.c       | 33 +++++++++++++++++++++++----------\n builtin/fast-export.c    |  2 ++\n builtin/mailsplit.c      | 10 ++++++++++\n builtin/mktree.c         |  5 +++--\n builtin/name-rev.c       |  7 +++++--\n builtin/pack-redundant.c |  1 +\n builtin/receive-pack.c   |  4 +++-\n builtin/worktree.c       |  8 +++++---\n compat/mingw.c           |  4 +++-\n compat/winansi.c         | 12 ++++++++++++\n config.c                 |  5 ++++-\n line-log.c               |  1 +\n mailinfo.c               |  9 ++++++++-\n patch-ids.c              |  3 ++-\n reflog-walk.c            | 20 +++++++++++++++++---\n remote.c                 |  5 +++--\n setup.c                  | 11 ++++++++---\n shallow.c                |  8 ++++++--\n worktree.c               |  2 +-\n wt-status.c              | 29 +++++++++++++++--------------\n 23 files changed, 148 insertions(+), 64 deletions(-)\n\n\nbase-commit: d2bbb7c2bcf6e77ebfcabf4e12110fe6d5c91de6\nPublished-As: https://github.com/dscho/git/releases/tag/coverity-v4\nFetch-It-Via: git fetch https://github.com/dscho/git coverity-v4\n\nInterdiff vs v3:\n\n diff --git a/compat/winansi.c b/compat/winansi.c\n index 861b79d8c31..a11a0f16d27 100644\n --- a/compat/winansi.c\n +++ b/compat/winansi.c\n @@ -105,8 +105,13 @@ static int is_console(int fd)\n  \tif (!fd) {\n  \t\tif (!GetConsoleMode(hcon, &mode))\n  \t\t\treturn 0;\n -\t\tsbi.wAttributes = FOREGROUND_BLUE | FOREGROUND_GREEN |\n -\t\t\tFOREGROUND_RED;\n +\t\t/*\n +\t\t * This code path is only reached if there is no console\n +\t\t * attached to stdout/stderr, i.e. we will not need to output\n +\t\t * any text to any console, therefore we might just as well\n +\t\t * use black as foreground color.\n +\t\t */\n +\t\tsbi.wAttributes = 0;\n  \t} else if (!GetConsoleScreenBufferInfo(hcon, &sbi))\n  \t\treturn 0;\n  \n diff --git a/wt-status.c b/wt-status.c\n index 1f3f6bcb980..117ac8cfb01 100644\n --- a/wt-status.c\n +++ b/wt-status.c\n @@ -1082,34 +1082,29 @@ static char *read_line_from_git_path(const char *filename)\n  static int split_commit_in_progress(struct wt_status *s)\n  {\n  \tint split_in_progress = 0;\n -\tchar *head = read_line_from_git_path(\"HEAD\");\n -\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n -\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n -\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n -\n -\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n -\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n -\t\tfree(head);\n -\t\tfree(orig_head);\n -\t\tfree(rebase_amend);\n -\t\tfree(rebase_orig_head);\n -\t\treturn split_in_progress;\n -\t}\n -\n -\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n -\t\tif (strcmp(head, rebase_amend))\n -\t\t\tsplit_in_progress = 1;\n -\t} else if (strcmp(orig_head, rebase_orig_head)) {\n -\t\tsplit_in_progress = 1;\n -\t}\n +\tchar *head, *orig_head, *rebase_amend, *rebase_orig_head;\n +\n +\tif ((!s->amend && !s->nowarn && !s->workdir_dirty) ||\n +\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n +\t\treturn 0;\n  \n -\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n -\t\tsplit_in_progress = 0;\n +\thead = read_line_from_git_path(\"HEAD\");\n +\torig_head = read_line_from_git_path(\"ORIG_HEAD\");\n +\trebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n +\trebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n +\n +\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head)\n +\t\t; /* fall through, no split in progress */\n +\telse if (!strcmp(rebase_amend, rebase_orig_head))\n +\t\tsplit_in_progress = !!strcmp(head, rebase_amend);\n +\telse if (strcmp(orig_head, rebase_orig_head))\n +\t\tsplit_in_progress = 1;\n  \n  \tfree(head);\n  \tfree(orig_head);\n  \tfree(rebase_amend);\n  \tfree(rebase_orig_head);\n +\n  \treturn split_in_progress;\n  }\n  \n\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318769","messageId":"1857475d4f75b811f16802daaf1303855e3ea4f1.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 01/25] mingw: avoid memory leak when splitting PATH","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:24Z","receivedAt":"2017-05-04T13:56:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"In the (admittedly, concocted) case that PATH consists only of path\ndelimiters, we would leak the duplicated string.\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/mingw.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/compat/mingw.c b/compat/mingw.c\nindex 3fbfda5978b..fe0e3ccd248 100644\n--- a/compat/mingw.c\n+++ b/compat/mingw.c\n@@ -961,8 +961,10 @@ static char **get_path_split(void)\n \t\t\t++n;\n \t\t}\n \t}\n-\tif (!n)\n+\tif (!n) {\n+\t\tfree(envpath);\n \t\treturn NULL;\n+\t}\n \n \tALLOC_ARRAY(path, n + 1);\n \tp = envpath;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318770","messageId":"06f1457a87c9b6b5b4619682c8601bda18e3ff2a.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 03/25] winansi: avoid buffer overrun","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:55:34Z","receivedAt":"2017-05-04T13:56:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When we could not convert the UTF-8 sequence into Unicode for writing to\nthe Console, we should not try to write an insanely-long sequence of\ninvalid wide characters (mistaking the negative return value for an\nunsigned length).\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n compat/winansi.c | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/compat/winansi.c b/compat/winansi.c\nindex a551de90eb0..a11a0f16d27 100644\n--- a/compat/winansi.c\n+++ b/compat/winansi.c\n@@ -140,6 +140,11 @@ static void write_console(unsigned char *str, size_t len)\n \n \t/* convert utf-8 to utf-16 */\n \tint wlen = xutftowcsn(wbuf, (char*) str, ARRAY_SIZE(wbuf), len);\n+\tif (wlen < 0) {\n+\t\twchar_t *err = L\"[invalid]\";\n+\t\tWriteConsoleW(console, err, wcslen(err), &dummy, NULL);\n+\t\treturn;\n+\t}\n \n \t/* write directly to console */\n \tWriteConsoleW(console, wbuf, wlen, &dummy, NULL);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318771","messageId":"4a707986baa04875ef59f7c17886df8fe52e704c.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 10/25] cat-file: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:17Z","receivedAt":"2017-05-04T13:56:53Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/cat-file.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/cat-file.c b/builtin/cat-file.c\nindex 1890d7a6390..9af863e7915 100644\n--- a/builtin/cat-file.c\n+++ b/builtin/cat-file.c\n@@ -165,6 +165,7 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,\n \t\tdie(\"git cat-file %s: bad file\", obj_name);\n \n \twrite_or_die(1, buf, size);\n+\tfree(buf);\n \treturn 0;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318772","messageId":"2704e145927c851c4163a68cfdfd5ada48fff21d.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 11/25] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:40Z","receivedAt":"2017-05-04T13:56:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This change addresses part of the NEEDSWORK comment above the code,\ntherefore the comment needs to be adjusted, too.\n\nDiscovered via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/checkout.c | 17 +++++++++--------\n 1 file changed, 9 insertions(+), 8 deletions(-)\n\ndiff --git a/builtin/checkout.c b/builtin/checkout.c\nindex bfa5419f335..5faea3a05fa 100644\n--- a/builtin/checkout.c\n+++ b/builtin/checkout.c\n@@ -235,14 +235,14 @@ static int checkout_merged(int pos, const struct checkout *state)\n \t/*\n \t * NEEDSWORK:\n \t * There is absolutely no reason to write this as a blob object\n-\t * and create a phony cache entry just to leak.  This hack is\n-\t * primarily to get to the write_entry() machinery that massages\n-\t * the contents to work-tree format and writes out which only\n-\t * allows it for a cache entry.  The code in write_entry() needs\n-\t * to be refactored to allow us to feed a <buffer, size, mode>\n-\t * instead of a cache entry.  Such a refactoring would help\n-\t * merge_recursive as well (it also writes the merge result to the\n-\t * object database even when it may contain conflicts).\n+\t * and create a phony cache entry.  This hack is primarily to get\n+\t * to the write_entry() machinery that massages the contents to\n+\t * work-tree format and writes out which only allows it for a\n+\t * cache entry.  The code in write_entry() needs to be refactored\n+\t * to allow us to feed a <buffer, size, mode> instead of a cache\n+\t * entry.  Such a refactoring would help merge_recursive as well\n+\t * (it also writes the merge result to the object database even\n+\t * when it may contain conflicts).\n \t */\n \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n \t\t\t    blob_type, oid.hash))\n@@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n \tif (!ce)\n \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n \tstatus = checkout_entry(ce, state, NULL);\n+\tfree(ce);\n \treturn status;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318773","messageId":"92b72e03dc5d5b0f9609556dddae1ebd871ee26f.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 18/25] receive-pack: plug memory leak in update()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:57:55Z","receivedAt":"2017-05-04T13:58:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/receive-pack.c | 4 +++-\n 1 file changed, 3 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/receive-pack.c b/builtin/receive-pack.c\nindex f96834f42c9..48c07ddb659 100644\n--- a/builtin/receive-pack.c\n+++ b/builtin/receive-pack.c\n@@ -986,7 +986,8 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n {\n \tconst char *name = cmd->ref_name;\n \tstruct strbuf namespaced_name_buf = STRBUF_INIT;\n-\tconst char *namespaced_name, *ret;\n+\tstatic char *namespaced_name;\n+\tconst char *ret;\n \tstruct object_id *old_oid = &cmd->old_oid;\n \tstruct object_id *new_oid = &cmd->new_oid;\n \n@@ -997,6 +998,7 @@ static const char *update(struct command *cmd, struct shallow_info *si)\n \t}\n \n \tstrbuf_addf(&namespaced_name_buf, \"%s%s\", get_git_namespace(), name);\n+\tfree(namespaced_name);\n \tnamespaced_name = strbuf_detach(&namespaced_name_buf, NULL);\n \n \tif (is_ref_checked_out(namespaced_name)) {\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318774","messageId":"e03becb8f844f5d5a465b3871f3369f6bc561261.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 19/25] line-log: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:58:01Z","receivedAt":"2017-05-04T13:58:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Discovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n line-log.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/line-log.c b/line-log.c\nindex a23b910471b..b9087814b8c 100644\n--- a/line-log.c\n+++ b/line-log.c\n@@ -1125,6 +1125,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c\n \tchanged = process_all_files(&parent_range, rev, &queue, range);\n \tif (parent)\n \t\tadd_line_range(rev, parent, parent_range);\n+\tfree_line_log_data(parent_range);\n \treturn changed;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318775","messageId":"879e7b73a5e11ade4eb633c2306c6b9d9d4f6018.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 20/25] shallow: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:58:35Z","receivedAt":"2017-05-04T13:58:52Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n shallow.c | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/shallow.c b/shallow.c\nindex 25b6db989bf..f9370961f99 100644\n--- a/shallow.c\n+++ b/shallow.c\n@@ -473,11 +473,15 @@ static void paint_down(struct paint_info *info, const unsigned char *sha1,\n \tstruct commit_list *head = NULL;\n \tint bitmap_nr = (info->nr_bits + 31) / 32;\n \tsize_t bitmap_size = st_mult(sizeof(uint32_t), bitmap_nr);\n-\tuint32_t *tmp = xmalloc(bitmap_size); /* to be freed before return */\n-\tuint32_t *bitmap = paint_alloc(info);\n \tstruct commit *c = lookup_commit_reference_gently(sha1, 1);\n+\tuint32_t *tmp; /* to be freed before return */\n+\tuint32_t *bitmap;\n+\n \tif (!c)\n \t\treturn;\n+\n+\ttmp = xmalloc(bitmap_size);\n+\tbitmap = paint_alloc(info);\n \tmemset(bitmap, 0, bitmap_size);\n \tbitmap[id / 32] |= (1U << (id % 32));\n \tcommit_list_insert(c, &head);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318776","messageId":"70ba46de5c9ca9987e6a5f1a16904b59a7c7cb45.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 12/25] split_commit_in_progress(): simplify & fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:44Z","receivedAt":"2017-05-04T13:59:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"This function did a whole lot of unnecessary work, such as reading in\nfour files just to figure out that, oh, hey, we do not need to look at\nthem after all because the HEAD is not detached.\n\nSimplify the entire function to return early when possible, to read in\nthe files only when necessary, and to release the allocated memory\nalways (there was a leak, reported via Coverity, where we failed to\nrelease the allocated strings if the HEAD is not detached).\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n wt-status.c | 28 ++++++++++++++--------------\n 1 file changed, 14 insertions(+), 14 deletions(-)\n\ndiff --git a/wt-status.c b/wt-status.c\nindex 0a6e16dbe0f..117ac8cfb01 100644\n--- a/wt-status.c\n+++ b/wt-status.c\n@@ -1082,29 +1082,29 @@ static char *read_line_from_git_path(const char *filename)\n static int split_commit_in_progress(struct wt_status *s)\n {\n \tint split_in_progress = 0;\n-\tchar *head = read_line_from_git_path(\"HEAD\");\n-\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n-\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n-\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n+\tchar *head, *orig_head, *rebase_amend, *rebase_orig_head;\n \n-\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n+\tif ((!s->amend && !s->nowarn && !s->workdir_dirty) ||\n \t    !s->branch || strcmp(s->branch, \"HEAD\"))\n-\t\treturn split_in_progress;\n+\t\treturn 0;\n \n-\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n-\t\tif (strcmp(head, rebase_amend))\n-\t\t\tsplit_in_progress = 1;\n-\t} else if (strcmp(orig_head, rebase_orig_head)) {\n-\t\tsplit_in_progress = 1;\n-\t}\n+\thead = read_line_from_git_path(\"HEAD\");\n+\torig_head = read_line_from_git_path(\"ORIG_HEAD\");\n+\trebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n+\trebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n \n-\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n-\t\tsplit_in_progress = 0;\n+\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head)\n+\t\t; /* fall through, no split in progress */\n+\telse if (!strcmp(rebase_amend, rebase_orig_head))\n+\t\tsplit_in_progress = !!strcmp(head, rebase_amend);\n+\telse if (strcmp(orig_head, rebase_orig_head))\n+\t\tsplit_in_progress = 1;\n \n \tfree(head);\n \tfree(orig_head);\n \tfree(rebase_amend);\n \tfree(rebase_orig_head);\n+\n \treturn split_in_progress;\n }\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318777","messageId":"30ae776cee0d07706679d8f310ad97860a311e16.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 14/25] setup_discovered_git_dir(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:51Z","receivedAt":"2017-05-04T13:59:05Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The setup_explicit_git_dir() function does not take custody of the string\npassed as first parameter; we have to release it if we turned the value of\ngit_dir into an absolute path.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 9 +++++++--\n 1 file changed, 7 insertions(+), 2 deletions(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0320a9ad14c..e3f7699a902 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -703,11 +703,16 @@ static const char *setup_discovered_git_dir(const char *gitdir,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n+\t\tchar *to_free = NULL;\n+\t\tconst char *ret;\n+\n \t\tif (offset != cwd->len && !is_absolute_path(gitdir))\n-\t\t\tgitdir = real_pathdup(gitdir, 1);\n+\t\t\tgitdir = to_free = real_pathdup(gitdir, 1);\n \t\tif (chdir(cwd->buf))\n \t\t\tdie_errno(\"Could not come back to cwd\");\n-\t\treturn setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tret = setup_explicit_git_dir(gitdir, cwd, nongit_ok);\n+\t\tfree(to_free);\n+\t\treturn ret;\n \t}\n \n \t/* #16.2, #17.2, #20.2, #21.2, #24, #25, #28, #29 (see t1510) */\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318778","messageId":"ab93a2585d08b972a567351957177049a130a339.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 17/25] fast-export: avoid leaking memory in handle_tag()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:57:33Z","receivedAt":"2017-05-04T13:59:07Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Reported by, you guessed it, Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/fast-export.c | 2 ++\n 1 file changed, 2 insertions(+)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex e0220630d00..64617ad8e36 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -734,6 +734,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t\t\t     oid_to_hex(&tag->object.oid));\n \t\tcase DROP:\n \t\t\t/* Ignore this tag altogether */\n+\t\t\tfree(buf);\n \t\t\treturn;\n \t\tcase REWRITE:\n \t\t\tif (tagged->type != OBJ_COMMIT) {\n@@ -765,6 +766,7 @@ static void handle_tag(const char *name, struct tag *tag)\n \t       (int)(tagger_end - tagger), tagger,\n \t       tagger == tagger_end ? \"\" : \"\\n\",\n \t       (int)message_size, (int)message_size, message ? message : \"\");\n+\tfree(buf);\n }\n \n static struct commit *get_commit(struct rev_cmdline_entry *e, char *full_name)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318779","messageId":"b67d22e657400733c9bb5c78b8adff7b75a82280.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 16/25] mktree: plug memory leaks reported by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:57:28Z","receivedAt":"2017-05-04T13:59:11Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/mktree.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/mktree.c b/builtin/mktree.c\nindex de9b40fc63b..da0fd8cd706 100644\n--- a/builtin/mktree.c\n+++ b/builtin/mktree.c\n@@ -72,7 +72,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \tunsigned mode;\n \tenum object_type mode_type; /* object type derived from mode */\n \tenum object_type obj_type; /* object type derived from sha */\n-\tchar *path;\n+\tchar *path, *to_free = NULL;\n \tunsigned char sha1[20];\n \n \tptr = buf;\n@@ -102,7 +102,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t\tstruct strbuf p_uq = STRBUF_INIT;\n \t\tif (unquote_c_style(&p_uq, path, NULL))\n \t\t\tdie(\"invalid quoting\");\n-\t\tpath = strbuf_detach(&p_uq, NULL);\n+\t\tpath = to_free = strbuf_detach(&p_uq, NULL);\n \t}\n \n \t/*\n@@ -136,6 +136,7 @@ static void mktree_line(char *buf, size_t len, int nul_term_line, int allow_miss\n \t}\n \n \tappend_to_tree(mode, sha1, path);\n+\tfree(to_free);\n }\n \n int cmd_mktree(int ac, const char **av, const char *prefix)\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318780","messageId":"fc054bdc7754045b01655feee88a74203bdf128c.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 13/25] setup_bare_git_dir(): help static analysis","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:47Z","receivedAt":"2017-05-04T13:59:19Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Coverity reported a memory leak in this function. However, it can only\nbe called once, as setup_git_directory() changes global state and hence\nis not reentrant.\n\nMark the variable as static to indicate that this is a singleton.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n setup.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/setup.c b/setup.c\nindex 0309c278218..0320a9ad14c 100644\n--- a/setup.c\n+++ b/setup.c\n@@ -748,7 +748,7 @@ static const char *setup_bare_git_dir(struct strbuf *cwd, int offset,\n \n \t/* --work-tree is set without --git-dir; use discovered one */\n \tif (getenv(GIT_WORK_TREE_ENVIRONMENT) || git_work_tree_cfg) {\n-\t\tconst char *gitdir;\n+\t\tstatic const char *gitdir;\n \n \t\tgitdir = offset == cwd->len ? \".\" : xmemdupz(cwd->buf, offset);\n \t\tif (chdir(cwd->buf))\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318781","messageId":"6b8ebc4c43b4912fac7dc52c1a62727b2e8f57b3.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 21/25] add_reflog_for_walk: avoid memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:58:42Z","receivedAt":"2017-05-04T13:59:31Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"We free()d the `log` buffer when dwim_log() returned 1, but not when it\nreturned a larger value (which meant that it still allocated the buffer\nbut we simply ignored it).\n\nWhile in the vicinity, make sure that the `reflogs` structure as well as\nthe `branch` variable are released properly, too.\n\nIdentified by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n reflog-walk.c | 20 +++++++++++++++++---\n 1 file changed, 17 insertions(+), 3 deletions(-)\n\ndiff --git a/reflog-walk.c b/reflog-walk.c\nindex 99679f58255..c63eb1a3fd7 100644\n--- a/reflog-walk.c\n+++ b/reflog-walk.c\n@@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\tif (!reflogs || reflogs->nr == 0) {\n \t\t\tstruct object_id oid;\n \t\t\tchar *b;\n-\t\t\tif (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {\n+\t\t\tint ret = dwim_log(branch, strlen(branch),\n+\t\t\t\t\t   oid.hash, &b);\n+\t\t\tif (ret > 1)\n+\t\t\t\tfree(b);\n+\t\t\telse if (ret == 1) {\n \t\t\t\tif (reflogs) {\n \t\t\t\t\tfree(reflogs->ref);\n \t\t\t\t\tfree(reflogs);\n@@ -193,17 +197,27 @@ int add_reflog_for_walk(struct reflog_walk_info *info,\n \t\t\t\treflogs = read_complete_reflog(branch);\n \t\t\t}\n \t\t}\n-\t\tif (!reflogs || reflogs->nr == 0)\n+\t\tif (!reflogs || reflogs->nr == 0) {\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n+\t\t\tfree(branch);\n \t\t\treturn -1;\n+\t\t}\n \t\tstring_list_insert(&info->complete_reflogs, branch)->util\n \t\t\t= reflogs;\n \t}\n+\tfree(branch);\n \n \tcommit_reflog = xcalloc(1, sizeof(struct commit_reflog));\n \tif (recno < 0) {\n \t\tcommit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);\n \t\tif (commit_reflog->recno < 0) {\n-\t\t\tfree(branch);\n+\t\t\tif (reflogs) {\n+\t\t\t\tfree(reflogs->ref);\n+\t\t\t\tfree(reflogs);\n+\t\t\t}\n \t\t\tfree(commit_reflog);\n \t\t\treturn -1;\n \t\t}\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318782","messageId":"9bfe852b8f8e4abd1ec4ffea9b2f9867a8bb167b.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 22/25] remote: plug memory leak in match_explicit()","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:59:01Z","receivedAt":"2017-05-04T13:59:35Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The `guess_ref()` returns an allocated buffer of which `make_linked_ref()`\ndoes not take custody (`alloc_ref()` makes a copy), therefore we need to\nrelease the buffer afterwards.\n\nNoticed via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n remote.c | 5 +++--\n 1 file changed, 3 insertions(+), 2 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex 801137c72eb..72b4591b983 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -1191,9 +1191,10 @@ static int match_explicit(struct ref *src, struct ref *dst,\n \t\telse if (is_null_oid(&matched_src->new_oid))\n \t\t\terror(\"unable to delete '%s': remote ref does not exist\",\n \t\t\t      dst_value);\n-\t\telse if ((dst_guess = guess_ref(dst_value, matched_src)))\n+\t\telse if ((dst_guess = guess_ref(dst_value, matched_src))) {\n \t\t\tmatched_dst = make_linked_ref(dst_guess, dst_tail);\n-\t\telse\n+\t\t\tfree(dst_guess);\n+\t\t} else\n \t\t\terror(\"unable to push to unqualified destination: %s\\n\"\n \t\t\t      \"The destination refspec neither matches an \"\n \t\t\t      \"existing ref on the remote nor\\n\"\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318783","messageId":"8059540948d52fb613cee1023813f9d48dbe8e32.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 24/25] show_worktree(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:59:13Z","receivedAt":"2017-05-04T13:59:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"The buffer allocated by shorten_unambiguous_ref() needs to be released.\n\nDiscovered by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/worktree.c | 8 +++++---\n 1 file changed, 5 insertions(+), 3 deletions(-)\n\ndiff --git a/builtin/worktree.c b/builtin/worktree.c\nindex 1722a9bdc2a..ff5dfd2b102 100644\n--- a/builtin/worktree.c\n+++ b/builtin/worktree.c\n@@ -414,9 +414,11 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)\n \t\t\t\tfind_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));\n \t\tif (wt->is_detached)\n \t\t\tstrbuf_addstr(&sb, \"(detached HEAD)\");\n-\t\telse if (wt->head_ref)\n-\t\t\tstrbuf_addf(&sb, \"[%s]\", shorten_unambiguous_ref(wt->head_ref, 0));\n-\t\telse\n+\t\telse if (wt->head_ref) {\n+\t\t\tchar *ref = shorten_unambiguous_ref(wt->head_ref, 0);\n+\t\t\tstrbuf_addf(&sb, \"[%s]\", ref);\n+\t\t\tfree(ref);\n+\t\t} else\n \t\t\tstrbuf_addstr(&sb, \"(error)\");\n \t}\n \tprintf(\"%s\\n\", sb.buf);\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318784","messageId":"c34be4cbfa4f25bade20f3d6b2ae07d1c847f630.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 23/25] name-rev: avoid leaking memory in the `deref` case","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:59:06Z","receivedAt":"2017-05-04T13:59:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"When the `name_rev()` function is asked to dereference the tip name, it\nallocates memory. But when it turns out that another tip already\ndescribed the commit better than the current one, we forgot to release\nthe memory.\n\nPointed out by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/name-rev.c | 7 +++++--\n 1 file changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/name-rev.c b/builtin/name-rev.c\nindex 92a5d8a5d26..e7a3fe7ee70 100644\n--- a/builtin/name-rev.c\n+++ b/builtin/name-rev.c\n@@ -28,6 +28,7 @@ static void name_rev(struct commit *commit,\n \tstruct rev_name *name = (struct rev_name *)commit->util;\n \tstruct commit_list *parents;\n \tint parent_number = 1;\n+\tchar *to_free = NULL;\n \n \tparse_commit(commit);\n \n@@ -35,7 +36,7 @@ static void name_rev(struct commit *commit,\n \t\treturn;\n \n \tif (deref) {\n-\t\ttip_name = xstrfmt(\"%s^0\", tip_name);\n+\t\ttip_name = to_free = xstrfmt(\"%s^0\", tip_name);\n \n \t\tif (generation)\n \t\t\tdie(\"generation: %d, but deref?\", generation);\n@@ -53,8 +54,10 @@ static void name_rev(struct commit *commit,\n \t\tname->taggerdate = taggerdate;\n \t\tname->generation = generation;\n \t\tname->distance = distance;\n-\t} else\n+\t} else {\n+\t\tfree(to_free);\n \t\treturn;\n+\t}\n \n \tfor (parents = commit->parents;\n \t\t\tparents;\n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318785","messageId":"83eb0a0551b78103ec08a367f951c1c81df3662c.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 25/25] submodule_uses_worktrees(): plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:59:19Z","receivedAt":"2017-05-04T13:59:50Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"There is really no reason why we would need to hold onto the allocated\nstring longer than necessary.\n\nReported by Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n worktree.c | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n\ndiff --git a/worktree.c b/worktree.c\nindex bae787cf8d7..89a81b13de3 100644\n--- a/worktree.c\n+++ b/worktree.c\n@@ -399,6 +399,7 @@ int submodule_uses_worktrees(const char *path)\n \n \t/* The env would be set for the superproject. */\n \tget_common_dir_noenv(&sb, submodule_gitdir);\n+\tfree(submodule_gitdir);\n \n \t/*\n \t * The check below is only known to be good for repository format\n@@ -418,7 +419,6 @@ int submodule_uses_worktrees(const char *path)\n \t/* See if there is any file inside the worktrees directory. */\n \tdir = opendir(sb.buf);\n \tstrbuf_release(&sb);\n-\tfree(submodule_gitdir);\n \n \tif (!dir)\n \t\treturn 0;\n-- \n2.12.2.windows.2.800.gede8f145e06\n"},{"id":"318786","messageId":"1589b496a91522e13150179a885bf64c139178cf.1493906085.git.johannes.schindelin@gmx.de","threadId":"45809","inReplyTo":"cover.1493906084.git.johannes.schindelin@gmx.de","subject":"[PATCH v4 15/25] pack-redundant: plug memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-04T13:56:54Z","receivedAt":"2017-05-04T13:59:51Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Identified via Coverity.\n\nSigned-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n---\n builtin/pack-redundant.c | 1 +\n 1 file changed, 1 insertion(+)\n\ndiff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c\nindex 72c815844dd..cb1df1c7614 100644\n--- a/builtin/pack-redundant.c\n+++ b/builtin/pack-redundant.c\n@@ -442,6 +442,7 @@ static void minimize(struct pack_list **min)\n \t/* return if there are no objects missing from the unique set */\n \tif (missing->size == 0) {\n \t\t*min = unique;\n+\t\tfree(missing);\n \t\treturn;\n \t}\n \n-- \n2.12.2.windows.2.800.gede8f145e06\n\n\n"},{"id":"318897","messageId":"alpine.DEB.2.21.1.1705052227120.146734@virtualbox","threadId":"45809","inReplyTo":"alpine.DEB.2.20.1704282205320.3480@virtualbox","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-05T20:30:15Z","receivedAt":"2017-05-05T20:30:36Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\n\nOn Fri, 28 Apr 2017, Johannes Schindelin wrote:\n\n> On Fri, 28 Apr 2017, Stefan Beller wrote:\n> \n> > On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n> > <Johannes.Schindelin@gmx.de> wrote:\n> > \n> > > I still have to find the time to figure out one more detail: how to\n> > > download and extract the Coverity tool (the .zip archive has a\n> > > variable name for the top-level directory), and doing that only\n> > > every once in a while, say, only when there is no previously\n> > > unpacked tool, or it is already 4 weeks old.\n> > \n> > That is an interesting problem, which I ignored as the older versions\n> > of their tools still works once they release new versions. So I just\n> > manually check every once in a while if they have new versions out\n> > there.\n> > \n> > So if you find a nice solution to that problem, let me know, please.\n> \n> I think I have a working idea (jotting it down in the editor, untested):\n> \n> [... totally untested snippet ...]\n\nAnd now I edited it and tested it. The code is now part of the script I\nuse for pretty much all administrative (i.e. recurring and boring) tasks\nin the Git for Windows project:\n\n\thttps://github.com/git-for-windows/build-extra/commit/05b5342128\n\nMay it be useful to you, too, at least as a starting point,\nDscho\n"},{"id":"318932","messageId":"49fad7f1-0bad-dbd2-89ff-5476f9b5bf91@web.de","threadId":"45809","inReplyTo":"alpine.DEB.2.21.1.1705041231270.4905@virtualbox","subject":"Re: [PATCH v3 12/25] split_commit_in_progress(): fix memory leak","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2017-05-06T17:13:40Z","receivedAt":"2017-05-06T17:14:05Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 04.05.2017 um 12:59 schrieb Johannes Schindelin:\n> Hi René,\n> \n> On Wed, 3 May 2017, René Scharfe wrote:\n> \n>> Am 02.05.2017 um 18:02 schrieb Johannes Schindelin:\n>>> Reported via Coverity.\n>>>\n>>> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n>>> ---\n>>>    wt-status.c | 7 ++++++-\n>>>    1 file changed, 6 insertions(+), 1 deletion(-)\n>>>\n>>> diff --git a/wt-status.c b/wt-status.c\n>>> index 0a6e16dbe0f..1f3f6bcb980 100644\n>>> --- a/wt-status.c\n>>> +++ b/wt-status.c\n>>> @@ -1088,8 +1088,13 @@ static int split_commit_in_progress(struct wt_status\n>>> *s)\n>>>     char *rebase_orig_head =\n>>>     read_line_from_git_path(\"rebase-merge/orig-head\");\n>>>    \n>>>    \tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n>>> -\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n>>> +\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n>>> +\t\tfree(head);\n>>> +\t\tfree(orig_head);\n>>> +\t\tfree(rebase_amend);\n>>> +\t\tfree(rebase_orig_head);\n>>>    \t\treturn split_in_progress;\n>>> +\t}\n>>>    \n>>>     if (!strcmp(rebase_amend, rebase_orig_head)) {\n>>>      if (strcmp(head, rebase_amend))\n>>>\n>>\n>> The return line could be replaced by \"; else\" to achieve the same\n>> result, without duplicating the free calls.\n> \n> True. It is much harder to explain it that way, though: the context looks\n> like this:\n> \n> static int split_commit_in_progress(struct wt_status *s)\n>   {\n>          int split_in_progress = 0;\n>          char *head = read_line_from_git_path(\"HEAD\");\n>          char *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n>          char *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n>          char *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n> \n>          if (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n> -           !s->branch || strcmp(s->branch, \"HEAD\"))\n> +           !s->branch || strcmp(s->branch, \"HEAD\")) {\n> +               free(head);\n> +               free(orig_head);\n> +               free(rebase_amend);\n> +               free(rebase_orig_head);\n>                  return split_in_progress;\n> +       }\n> \n>          if (!strcmp(rebase_amend, rebase_orig_head)) {\n>                  if (strcmp(head, rebase_amend))\n>                          split_in_progress = 1;\n>          } else if (strcmp(orig_head, rebase_orig_head)) {\n>                  split_in_progress = 1;\n>          }\n> \n>          if (!s->amend && !s->nowarn && !s->workdir_dirty)\n>                  split_in_progress = 0;\n> \n>          free(head);\n>          free(orig_head);\n>          free(rebase_amend);\n>          free(rebase_orig_head);\n>          return split_in_progress;\n>   }\n> \n> So as you see, if we make the change you suggested, the next if() is hit\n> which possibly sets split_in_progress = 0.\n> \n> The thing is: this variable has been initialized to 0 in the beginning! So\n> this conditional assignment would be a noop, unless any of the code paths\n> before this conditional modified split_in_progress.\n\nRight. It could have been used as a quick two-line fix.\n\n> After you fully wrapped your head around this code, I am sure you agree\n> that the code is unnecessarily confusing to begin with: why do we go out\n> of our way to allocate and read all those strings, compare them to figure\n> out whether there is a split in progress, just to look at bits in the\n> wt_status struct (that we had available from the beginning) to potentially\n> undo all of that.\n\nThe only function with a higher cyclomatic complexity in this file is\nwt_longstatus_print(), which spans more than 100 lines.  Amazing.\n\n> What's worse, I cannot even find a logical explanation why the code is so\n> confusing, as it has been added as it is today in commit 2d1ccebae41\n> (status: better advices when splitting a commit (during rebase -i),\n> 2012-06-10).\n\nRepeatedly I get the impression that defects or shortcomings tend to\ncluster.  It pays to take a good look at the code surrounding a find of\nan automatic checker for other possible improvements.\n\n> So I think this function really wants to be fixed more fully (although I\n> feel bad for inserting such a non-trivial fix into a patch series\n> otherwise populated by trivial memory/resource leak plugs):\n\nIt could be done in two steps.  Doing it in one is probably OK as well.\n\n> -- snipsnap --\n> Subject: [PATCH] squash! split_commit_in_progress(): fix memory leak\n> \n> split_commit_in_progress(): simplify & fix memory leak\n> \n> This function did a whole lot of unnecessary work, such as reading in\n> four files just to figure out that, oh, hey, we do not need to look at\n> them after all because the HEAD is not detached.\n> \n> Simplify the entire function to return early when possible, to read in\n> the files only when necessary, and to release the allocated memory\n> always (there was a leak, reported via Coverity, where we failed to\n> release the allocated strings if the HEAD is not detached).\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>   wt-status.c | 39 +++++++++++++++++----------------------\n>   1 file changed, 17 insertions(+), 22 deletions(-)\n> \n> diff --git a/wt-status.c b/wt-status.c\n> index 1f3f6bcb980..117ac8cfb01 100644\n> --- a/wt-status.c\n> +++ b/wt-status.c\n> @@ -1082,34 +1082,29 @@ static char *read_line_from_git_path(const char *filename)\n>   static int split_commit_in_progress(struct wt_status *s)\n>   {\n>   \tint split_in_progress = 0;\n> -\tchar *head = read_line_from_git_path(\"HEAD\");\n> -\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> -\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> -\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n> -\n> -\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n> -\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n> -\t\tfree(head);\n> -\t\tfree(orig_head);\n> -\t\tfree(rebase_amend);\n> -\t\tfree(rebase_orig_head);\n> -\t\treturn split_in_progress;\n> -\t}\n> -\n> -\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n> -\t\tif (strcmp(head, rebase_amend))\n> -\t\t\tsplit_in_progress = 1;\n> -\t} else if (strcmp(orig_head, rebase_orig_head)) {\n> -\t\tsplit_in_progress = 1;\n> -\t}\n> +\tchar *head, *orig_head, *rebase_amend, *rebase_orig_head;\n> +\n> +\tif ((!s->amend && !s->nowarn && !s->workdir_dirty) ||\n> +\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n> +\t\treturn 0;\n>   \n> -\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n> -\t\tsplit_in_progress = 0;\n> +\thead = read_line_from_git_path(\"HEAD\");\n> +\torig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> +\trebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> +\trebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n\nFurther improvement idea (for a later series): Use rebase_path_amend()\nand rebase_path_orig_head() somehow, to build each path only once.\n\nAccessing the files HEAD and ORIG_HEAD directly seems odd.\n\nThe second part of the function should probably be moved to sequencer.c.\n\n> +\n> +\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head)\n> +\t\t; /* fall through, no split in progress */\n\nYou could set split_in_progress to zero here.  Would save a comment\nwithout losing readability.\n\n> +\telse if (!strcmp(rebase_amend, rebase_orig_head))\n> +\t\tsplit_in_progress = !!strcmp(head, rebase_amend);\n> +\telse if (strcmp(orig_head, rebase_orig_head))\n> +\t\tsplit_in_progress = 1;\n>   \n>   \tfree(head);\n>   \tfree(orig_head);\n>   \tfree(rebase_amend);\n>   \tfree(rebase_orig_head);\n> +\n\nIsn't the patch big enough already without rearranging the else blocks\nand adding that blank line? :)\n\n>   \treturn split_in_progress;\n>   }\n>   \n> \n"},{"id":"318936","messageId":"36a581f6-077e-ca89-49d0-ad487ff222a3@web.de","threadId":"45809","inReplyTo":"2704e145927c851c4163a68cfdfd5ada48fff21d.1493906085.git.johannes.schindelin@gmx.de","subject":"Re: [PATCH v4 11/25] checkout: fix memory leak","fromName":"René Scharfe","fromEmail":"l.s.r@web.de","sentAt":"2017-05-06T17:14:01Z","receivedAt":"2017-05-06T17:14:32Z","isPatch":true,"sender":{"key":"l.s.r@web.de","avatar":"https://avatars.githubusercontent.com/u/26122331?v=4"},"body":"Am 04.05.2017 um 15:56 schrieb Johannes Schindelin:\n> This change addresses part of the NEEDSWORK comment above the code,\n> therefore the comment needs to be adjusted, too.\n> \n> Discovered via Coverity.\n> \n> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>\n> ---\n>   builtin/checkout.c | 17 +++++++++--------\n>   1 file changed, 9 insertions(+), 8 deletions(-)\n> \n> diff --git a/builtin/checkout.c b/builtin/checkout.c\n> index bfa5419f335..5faea3a05fa 100644\n> --- a/builtin/checkout.c\n> +++ b/builtin/checkout.c\n> @@ -235,14 +235,14 @@ static int checkout_merged(int pos, const struct checkout *state)\n>   \t/*\n>   \t * NEEDSWORK:\n>   \t * There is absolutely no reason to write this as a blob object\n> -\t * and create a phony cache entry just to leak.  This hack is\n> -\t * primarily to get to the write_entry() machinery that massages\n> -\t * the contents to work-tree format and writes out which only\n> -\t * allows it for a cache entry.  The code in write_entry() needs\n> -\t * to be refactored to allow us to feed a <buffer, size, mode>\n> -\t * instead of a cache entry.  Such a refactoring would help\n> -\t * merge_recursive as well (it also writes the merge result to the\n> -\t * object database even when it may contain conflicts).\n> +\t * and create a phony cache entry.  This hack is primarily to get\n> +\t * to the write_entry() machinery that massages the contents to\n> +\t * work-tree format and writes out which only allows it for a\n> +\t * cache entry.  The code in write_entry() needs to be refactored\n> +\t * to allow us to feed a <buffer, size, mode> instead of a cache\n> +\t * entry.  Such a refactoring would help merge_recursive as well\n> +\t * (it also writes the merge result to the object database even\n> +\t * when it may contain conflicts).\n>   \t */\n>   \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n>   \t\t\t    blob_type, oid.hash))\n\nRandom observation: Using pretend_sha1_file here would at least avoid\nwriting the blob.\n\n> @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n>   \tif (!ce)\n>   \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n>   \tstatus = checkout_entry(ce, state, NULL);\n> +\tfree(ce);\n>   \treturn status;\n>   }\n\nI wonder if that's safe.  Why document a leak when it could have been\nplugged this easily instead?  A leak is better than a use after free, so\nlet's be extra careful here.  Would it leave the index inconsistent?  Or\nperhaps freeing it has become safe in the meantime?\n\n@Junio: Do you remember the reason for the leaks in 0cf8581e330\n(checkout -m: recreate merge when checking out of unmerged index).\n\nAnd result_buf is still leaked here, right?\n\nFWIW, after fixing a different issue (patch just sent separately)\nt*checkout*.sh complete successfully for me with --valgrind, with and\nwithout freeing both ce and result_buf.ptr.  So it *seems* safe..\n\nRené\n"},{"id":"319029","messageId":"xmqqk25sch89.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"36a581f6-077e-ca89-49d0-ad487ff222a3@web.de","subject":"Re: [PATCH v4 11/25] checkout: fix memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-08T00:41:42Z","receivedAt":"2017-05-08T00:41:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"René Scharfe <l.s.r@web.de> writes:\n\n>>   \t/*\n>>   \t * NEEDSWORK:\n>>   \t * There is absolutely no reason to write this as a blob object\n>> -\t * and create a phony cache entry just to leak.  This hack is\n>> -\t * primarily to get to the write_entry() machinery that massages\n>> -\t * the contents to work-tree format and writes out which only\n>> -\t * allows it for a cache entry.  The code in write_entry() needs\n>> -\t * to be refactored to allow us to feed a <buffer, size, mode>\n>> -\t * instead of a cache entry.  Such a refactoring would help\n>> -\t * merge_recursive as well (it also writes the merge result to the\n>> -\t * object database even when it may contain conflicts).\n>> +\t * and create a phony cache entry.  This hack is primarily to get\n>> +\t * to the write_entry() machinery that massages the contents to\n>> +\t * work-tree format and writes out which only allows it for a\n>> +\t * cache entry.  The code in write_entry() needs to be refactored\n>> +\t * to allow us to feed a <buffer, size, mode> instead of a cache\n>> +\t * entry.  Such a refactoring would help merge_recursive as well\n>> +\t * (it also writes the merge result to the object database even\n>> +\t * when it may contain conflicts).\n>>   \t */\n>>   \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n>>   \t\t\t    blob_type, oid.hash))\n>\n> Random observation: Using pretend_sha1_file here would at least avoid\n> writing the blob.\n\nYup, you should have told that to me back in Aug 2008 ;-) when I did\n0cf8581e (\"checkout -m: recreate merge when checking out of unmerged\nindex\", 2008-08-30); pretend_sha1_file() was available since early\n2007, and there is no excuse that this codepath did not use it.\n>\n>> @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n>>   \tif (!ce)\n>>   \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n>>   \tstatus = checkout_entry(ce, state, NULL);\n>> +\tfree(ce);\n>>   \treturn status;\n>>   }\n>\n> I wonder if that's safe.  Why document a leak when it could have been\n> plugged this easily instead?\n>\n> A leak is better than a use after free, so\n> let's be extra careful here.  Would it leave the index inconsistent?  Or\n> perhaps freeing it has become safe in the meantime?\n>\n> @Junio: Do you remember the reason for the leaks in 0cf8581e330\n> (checkout -m: recreate merge when checking out of unmerged index).\n\nYes.\n\nIn the very old days it was not allowed to free(3) contents of\nactive_cache[] and this was an old brain fart that came out of\ninertia.  We are manufacturing a brand new ce, only to feed it to\ncheckout_entry() without even registering it to the active_cache[]\narray, and the ancient rule doesn't even apply to such a case.\n\nSo I think it was safe to free(3) even back then.\n\n> And result_buf is still leaked here, right?\n\nGood spotting.  It typically would make a larger leak than a single\nce, I would suppose ;-)\n"},{"id":"319197","messageId":"alpine.DEB.2.21.1.1705091536120.146734@virtualbox","threadId":"45809","inReplyTo":"49fad7f1-0bad-dbd2-89ff-5476f9b5bf91@web.de","subject":"Re: [PATCH v3 12/25] split_commit_in_progress(): fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-09T13:39:30Z","receivedAt":"2017-05-09T13:39:57Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi René,\n\nOn Sat, 6 May 2017, René Scharfe wrote:\n\n> Am 04.05.2017 um 12:59 schrieb Johannes Schindelin:\n>\n> > diff --git a/wt-status.c b/wt-status.c\n> > index 1f3f6bcb980..117ac8cfb01 100644\n> > --- a/wt-status.c\n> > +++ b/wt-status.c\n> > @@ -1082,34 +1082,29 @@ static char *read_line_from_git_path(const char\n> > *filename)\n> >   static int split_commit_in_progress(struct wt_status *s)\n> >   {\n> >   \tint split_in_progress = 0;\n> > -\tchar *head = read_line_from_git_path(\"HEAD\");\n> > -\tchar *orig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> > -\tchar *rebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> > -\tchar *rebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n> > -\n> > -\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head ||\n> > -\t    !s->branch || strcmp(s->branch, \"HEAD\")) {\n> > -\t\tfree(head);\n> > -\t\tfree(orig_head);\n> > -\t\tfree(rebase_amend);\n> > -\t\tfree(rebase_orig_head);\n> > -\t\treturn split_in_progress;\n> > -\t}\n> > -\n> > -\tif (!strcmp(rebase_amend, rebase_orig_head)) {\n> > -\t\tif (strcmp(head, rebase_amend))\n> > -\t\t\tsplit_in_progress = 1;\n> > -\t} else if (strcmp(orig_head, rebase_orig_head)) {\n> > -\t\tsplit_in_progress = 1;\n> > -\t}\n> > +\tchar *head, *orig_head, *rebase_amend, *rebase_orig_head;\n> > +\n> > +\tif ((!s->amend && !s->nowarn && !s->workdir_dirty) ||\n> > +\t    !s->branch || strcmp(s->branch, \"HEAD\"))\n> > +\t\treturn 0;\n> >   -\tif (!s->amend && !s->nowarn && !s->workdir_dirty)\n> > -\t\tsplit_in_progress = 0;\n> > +\thead = read_line_from_git_path(\"HEAD\");\n> > +\torig_head = read_line_from_git_path(\"ORIG_HEAD\");\n> > +\trebase_amend = read_line_from_git_path(\"rebase-merge/amend\");\n> > +\trebase_orig_head = read_line_from_git_path(\"rebase-merge/orig-head\");\n> \n> Further improvement idea (for a later series): Use rebase_path_amend()\n> and rebase_path_orig_head() somehow, to build each path only once.\n> \n> Accessing the files HEAD and ORIG_HEAD directly seems odd.\n> \n> The second part of the function should probably be moved to sequencer.c.\n\nSure. On all four accounts.\n\n> > +\n> > +\tif (!head || !orig_head || !rebase_amend || !rebase_orig_head)\n> > +\t\t; /* fall through, no split in progress */\n> \n> You could set split_in_progress to zero here.  Would save a comment\n> without losing readability.\n\nBut that would confuse e.g. myself, 6 months down the road: why assign\nthat variable when it already has been assigned? (And we have to assign it\nbecause there is still a code path entering none of these if/else if's\narms).\n\n> > +\telse if (!strcmp(rebase_amend, rebase_orig_head))\n> > +\t\tsplit_in_progress = !!strcmp(head, rebase_amend);\n> > +\telse if (strcmp(orig_head, rebase_orig_head))\n> > +\t\tsplit_in_progress = 1;\n> >   \n> >    free(head);\n> >    free(orig_head);\n> >    free(rebase_amend);\n> >    free(rebase_orig_head);\n> > +\n> \n> Isn't the patch big enough already without rearranging the else blocks\n> and adding that blank line? :)\n\nThe else blocks are not really rearranged; apart from the early return,\nthe rest of the logic has been painstakingly kept in the same order.\n\nCiao,\nDscho"},{"id":"319199","messageId":"alpine.DEB.2.21.1.1705091540130.146734@virtualbox","threadId":"45809","inReplyTo":"xmqqk25sch89.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v4 11/25] checkout: fix memory leak","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-09T13:42:17Z","receivedAt":"2017-05-09T13:42:34Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio & René,\n\nOn Mon, 8 May 2017, Junio C Hamano wrote:\n\n> René Scharfe <l.s.r@web.de> writes:\n> \n> >>   \t/*\n> >>   \t * NEEDSWORK:\n> >>   \t * There is absolutely no reason to write this as a blob object\n> >> -\t * and create a phony cache entry just to leak.  This hack is\n> >> -\t * primarily to get to the write_entry() machinery that massages\n> >> -\t * the contents to work-tree format and writes out which only\n> >> -\t * allows it for a cache entry.  The code in write_entry() needs\n> >> -\t * to be refactored to allow us to feed a <buffer, size, mode>\n> >> -\t * instead of a cache entry.  Such a refactoring would help\n> >> -\t * merge_recursive as well (it also writes the merge result to the\n> >> -\t * object database even when it may contain conflicts).\n> >> +\t * and create a phony cache entry.  This hack is primarily to get\n> >> +\t * to the write_entry() machinery that massages the contents to\n> >> +\t * work-tree format and writes out which only allows it for a\n> >> +\t * cache entry.  The code in write_entry() needs to be refactored\n> >> +\t * to allow us to feed a <buffer, size, mode> instead of a cache\n> >> +\t * entry.  Such a refactoring would help merge_recursive as well\n> >> +\t * (it also writes the merge result to the object database even\n> >> +\t * when it may contain conflicts).\n> >>   \t */\n> >>   \tif (write_sha1_file(result_buf.ptr, result_buf.size,\n> >>   \t\t\t    blob_type, oid.hash))\n> >\n> > Random observation: Using pretend_sha1_file here would at least avoid\n> > writing the blob.\n> \n> Yup, you should have told that to me back in Aug 2008 ;-) when I did\n> 0cf8581e (\"checkout -m: recreate merge when checking out of unmerged\n> index\", 2008-08-30); pretend_sha1_file() was available since early\n> 2007, and there is no excuse that this codepath did not use it.\n\nI hope y'all agree that this is outside the scope of my patch series...\n\n> >> @@ -251,6 +251,7 @@ static int checkout_merged(int pos, const struct checkout *state)\n> >>   \tif (!ce)\n> >>   \t\tdie(_(\"make_cache_entry failed for path '%s'\"), path);\n> >>   \tstatus = checkout_entry(ce, state, NULL);\n> >> +\tfree(ce);\n> >>   \treturn status;\n> >>   }\n> >\n> > I wonder if that's safe.  Why document a leak when it could have been\n> > plugged this easily instead?\n> >\n> > A leak is better than a use after free, so\n> > let's be extra careful here.  Would it leave the index inconsistent?  Or\n> > perhaps freeing it has become safe in the meantime?\n> >\n> > @Junio: Do you remember the reason for the leaks in 0cf8581e330\n> > (checkout -m: recreate merge when checking out of unmerged index).\n> \n> Yes.\n> \n> In the very old days it was not allowed to free(3) contents of\n> active_cache[] and this was an old brain fart that came out of\n> inertia.  We are manufacturing a brand new ce, only to feed it to\n> checkout_entry() without even registering it to the active_cache[]\n> array, and the ancient rule doesn't even apply to such a case.\n> \n> So I think it was safe to free(3) even back then.\n\nSo this patch is good, then?\n\n> > And result_buf is still leaked here, right?\n> \n> Good spotting.  It typically would make a larger leak than a single\n> ce, I would suppose ;-)\n\nI saw you added this as a fixup! commit. If you don't mind, and if no\nother changes are requested, would you mind rebase'ing this yourself?\n\nThanks,\nDscho"},{"id":"319235","messageId":"xmqq4lwt1w54.fsf@gitster.mtv.corp.google.com","threadId":"45809","inReplyTo":"alpine.DEB.2.21.1.1705091540130.146734@virtualbox","subject":"Re: [PATCH v4 11/25] checkout: fix memory leak","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2017-05-09T22:51:51Z","receivedAt":"2017-05-09T22:52:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> > A leak is better than a use after free, so\n>> > let's be extra careful here.  Would it leave the index inconsistent?  Or\n>> > perhaps freeing it has become safe in the meantime?\n>> >\n>> > @Junio: Do you remember the reason for the leaks in 0cf8581e330\n>> > (checkout -m: recreate merge when checking out of unmerged index).\n>> \n>> Yes.\n>> \n>> In the very old days it was not allowed to free(3) contents of\n>> active_cache[] and this was an old brain fart that came out of\n>> inertia.  We are manufacturing a brand new ce, only to feed it to\n>> checkout_entry() without even registering it to the active_cache[]\n>> array, and the ancient rule doesn't even apply to such a case.\n>> \n>> So I think it was safe to free(3) even back then.\n>\n> So this patch is good, then?\n\nUnless I from this year is failing to spot a breakage that will be\ncaused in the codepath that I from year 2008 and René spotted, I\nthink freeing ce after we are done updating the working tree file\nwith it is safe.  I'd need to find time to make sure, though.\n\n>> > And result_buf is still leaked here, right?\n>> \n>> Good spotting.  It typically would make a larger leak than a single\n>> ce, I would suppose ;-)\n>\n> I saw you added this as a fixup! commit. If you don't mind, and if no\n> other changes are requested, would you mind rebase'ing this yourself?\n\nI think it would be better to leave the fix as a separate patch.  It\nwasn't spotted by Coverity in the first place ;-)\n"},{"id":"319292","messageId":"alpine.DEB.2.21.1.1705101801300.146734@virtualbox","threadId":"45809","inReplyTo":"alpine.DEB.2.21.1.1705052227120.146734@virtualbox","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-10T19:48:46Z","receivedAt":"2017-05-10T19:48:59Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\nOn Fri, 5 May 2017, Johannes Schindelin wrote:\n\n> On Fri, 28 Apr 2017, Johannes Schindelin wrote:\n> \n> > On Fri, 28 Apr 2017, Stefan Beller wrote:\n> > \n> > > On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n> > > <Johannes.Schindelin@gmx.de> wrote:\n> > > \n> > > > I still have to find the time to figure out one more detail: how\n> > > > to download and extract the Coverity tool (the .zip archive has a\n> > > > variable name for the top-level directory), and doing that only\n> > > > every once in a while, say, only when there is no previously\n> > > > unpacked tool, or it is already 4 weeks old.\n> > > \n> > > That is an interesting problem, which I ignored as the older\n> > > versions of their tools still works once they release new versions.\n> > > So I just manually check every once in a while if they have new\n> > > versions out there.\n> > > \n> > > So if you find a nice solution to that problem, let me know, please.\n> > \n> > I think I have a working idea (jotting it down in the editor,\n> > untested):\n> > \n> > [... totally untested snippet ...]\n> \n> And now I edited it and tested it. The code is now part of the script I\n> use for pretty much all administrative (i.e. recurring and boring) tasks\n> in the Git for Windows project:\n> \n> \thttps://github.com/git-for-windows/build-extra/commit/05b5342128\n\nOh, I completely forgot to mention that I tried to set the FLEX_ARRAY\nconstant to something quite large (I used 64k), but apparently that does\nnot work as expected, Coverity still insists on complaining about strbufs.\n\nOn a second thought, it is actually quite obvious why it does not fix\nthose reports: STRBUF_INIT has nothing to do with FLEX_ARRAY. D'oh.\n\nMy next attempt to work around these bogus claims was to modify the \"model\nfile\" by adding a line saying \"char strbuf_slopbuf[64];\", but that was\nsadly not picked up by Coverity either.\n\nMy current thinking is that I will simply patch strbuf.c via `sed\n's/^\\(char struct_slopbuf\\[\\)1\\[/&64[/'`.\n\nCiao,\nDscho\n"},{"id":"319293","messageId":"CAGZ79kaAYU3cSRdXZTvukib3VNmx+_GdeSV5NkZ1g_OWt07i9A@mail.gmail.com","threadId":"45809","inReplyTo":"alpine.DEB.2.21.1.1705101801300.146734@virtualbox","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2017-05-10T19:54:29Z","receivedAt":"2017-05-10T19:54:36Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Wed, May 10, 2017 at 12:48 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Stefan,\n>\n> On Fri, 5 May 2017, Johannes Schindelin wrote:\n>\n>> On Fri, 28 Apr 2017, Johannes Schindelin wrote:\n>>\n>> > On Fri, 28 Apr 2017, Stefan Beller wrote:\n>> >\n>> > > On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n>> > > <Johannes.Schindelin@gmx.de> wrote:\n>> > >\n>> > > > I still have to find the time to figure out one more detail: how\n>> > > > to download and extract the Coverity tool (the .zip archive has a\n>> > > > variable name for the top-level directory), and doing that only\n>> > > > every once in a while, say, only when there is no previously\n>> > > > unpacked tool, or it is already 4 weeks old.\n>> > >\n>> > > That is an interesting problem, which I ignored as the older\n>> > > versions of their tools still works once they release new versions.\n>> > > So I just manually check every once in a while if they have new\n>> > > versions out there.\n>> > >\n>> > > So if you find a nice solution to that problem, let me know, please.\n>> >\n>> > I think I have a working idea (jotting it down in the editor,\n>> > untested):\n>> >\n>> > [... totally untested snippet ...]\n>>\n>> And now I edited it and tested it. The code is now part of the script I\n>> use for pretty much all administrative (i.e. recurring and boring) tasks\n>> in the Git for Windows project:\n>>\n>>       https://github.com/git-for-windows/build-extra/commit/05b5342128\n>\n> Oh, I completely forgot to mention that I tried to set the FLEX_ARRAY\n> constant to something quite large (I used 64k), but apparently that does\n> not work as expected, Coverity still insists on complaining about strbufs.\n>\n> On a second thought, it is actually quite obvious why it does not fix\n> those reports: STRBUF_INIT has nothing to do with FLEX_ARRAY. D'oh.\n\nD'oh. I must have been living in an alternate universe for quite some time\nas I seemed to have confused different things here.\n\nCheckout this commit,\nhttps://github.com/stefanbeller/git/commit/977f81d6dec4461a1a12da2df6c5c919b41129b4\nthat is cherry-picked for the coverity build. That fixes it.\n\nThat is about the only patch I apply before sending it off to coverity.\nI am still contemplating a nice solution for FLEX_ARRAYs in other cases.\n\nThanks,\nStefan\n"},{"id":"319388","messageId":"alpine.DEB.2.21.1.1705111329140.146734@virtualbox","threadId":"45809","inReplyTo":"CAGZ79kaAYU3cSRdXZTvukib3VNmx+_GdeSV5NkZ1g_OWt07i9A@mail.gmail.com","subject":"Re: Automating Coverity, was Re: [PATCH 00/26] Address a couple of issues identified by Coverity","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2017-05-11T11:33:17Z","receivedAt":"2017-05-11T11:33:47Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Stefan,\n\nOn Wed, 10 May 2017, Stefan Beller wrote:\n\n> On Wed, May 10, 2017 at 12:48 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Fri, 5 May 2017, Johannes Schindelin wrote:\n> >\n> >> On Fri, 28 Apr 2017, Johannes Schindelin wrote:\n> >>\n> >> > On Fri, 28 Apr 2017, Stefan Beller wrote:\n> >> >\n> >> > > On Thu, Apr 27, 2017 at 3:50 PM, Johannes Schindelin\n> >> > > <Johannes.Schindelin@gmx.de> wrote:\n> >> > >\n> >> > > > I still have to find the time to figure out one more detail: how\n> >> > > > to download and extract the Coverity tool (the .zip archive has a\n> >> > > > variable name for the top-level directory), and doing that only\n> >> > > > every once in a while, say, only when there is no previously\n> >> > > > unpacked tool, or it is already 4 weeks old.\n> >> > >\n> >> > > That is an interesting problem, which I ignored as the older\n> >> > > versions of their tools still works once they release new versions.\n> >> > > So I just manually check every once in a while if they have new\n> >> > > versions out there.\n> >> > >\n> >> > > So if you find a nice solution to that problem, let me know, please.\n> >> >\n> >> > I think I have a working idea (jotting it down in the editor,\n> >> > untested):\n> >> >\n> >> > [... totally untested snippet ...]\n> >>\n> >> And now I edited it and tested it. The code is now part of the script I\n> >> use for pretty much all administrative (i.e. recurring and boring) tasks\n> >> in the Git for Windows project:\n> >>\n> >>       https://github.com/git-for-windows/build-extra/commit/05b5342128\n> >\n> > Oh, I completely forgot to mention that I tried to set the FLEX_ARRAY\n> > constant to something quite large (I used 64k), but apparently that does\n> > not work as expected, Coverity still insists on complaining about strbufs.\n> >\n> > On a second thought, it is actually quite obvious why it does not fix\n> > those reports: STRBUF_INIT has nothing to do with FLEX_ARRAY. D'oh.\n> \n> D'oh. I must have been living in an alternate universe for quite some time\n> as I seemed to have confused different things here.\n> \n> Checkout this commit,\n> https://github.com/stefanbeller/git/commit/977f81d6dec4461a1a12da2df6c5c919b41129b4\n> that is cherry-picked for the coverity build. That fixes it.\n\nI saw that patch, and since Junio did not pick it up, I figured that it\nwon't make it into git.git's source code. That's why I went with the `sed`\napproach, as the #ifndef __COVERITY__ guard is not even necessary if I\nhave to patch the code before running the Coverity tool anyway.\n\n> That is about the only patch I apply before sending it off to coverity.\n> I am still contemplating a nice solution for FLEX_ARRAYs in other cases.\n\nFor FLEX_ARRAYs, I use this:\n\n\tcov-build --dir cov-int \\\n                make -j15 DEVELOPER=1 CPPFLAGS=-DFLEX_ARRAY=65536\n\nI have not had time to go over more than half a dozen CIDs, but I *think*\nit helps.\n\nCiao,\nDscho\n"}]}