add_reflog_for_walk: avoid memory leak

We free()d the `log` buffer when dwim_log() returned 1, but not when it returned a larger value (which meant that it still allocated the buffer but we simply ignored it). While in the vicinity, make sure that the `reflogs` structure as well as the `branch` variable are released properly, too. Identified by Coverity. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed May 4, 2017 at 15:58 UTC 5026b471751092ab971f3d4ae46320bc8ce40ff5
1 file changed +17 -3
reflog-walk.c
+17 -3
@@ -183,7 +183,11 @@ int add_reflog_for_walk(struct reflog_walk_info *info,
183 if (!reflogs || reflogs->nr == 0) {
184 struct object_id oid;
185 char *b;
186 - if (dwim_log(branch, strlen(branch), oid.hash, &b) == 1) {
186 + int ret = dwim_log(branch, strlen(branch),
187 + oid.hash, &b);
188 + if (ret > 1)
189 + free(b);
190 + else if (ret == 1) {
191 if (reflogs) {
192 free(reflogs->ref);
193 free(reflogs);
@@ -193,17 +197,27 @@ int add_reflog_for_walk(struct reflog_walk_info *info,
197 reflogs = read_complete_reflog(branch);
198 }
199 }
196 - if (!reflogs || reflogs->nr == 0)
200 + if (!reflogs || reflogs->nr == 0) {
201 + if (reflogs) {
202 + free(reflogs->ref);
203 + free(reflogs);
204 + }
205 + free(branch);
206 return -1;
207 + }
208 string_list_insert(&info->complete_reflogs, branch)->util
209 = reflogs;
210 }
211 + free(branch);
212
213 commit_reflog = xcalloc(1, sizeof(struct commit_reflog));
214 if (recno < 0) {
215 commit_reflog->recno = get_reflog_recno_by_time(reflogs, timestamp);
216 if (commit_reflog->recno < 0) {
206 - free(branch);
217 + if (reflogs) {
218 + free(reflogs->ref);
219 + free(reflogs);
220 + }
221 free(commit_reflog);
222 return -1;
223 }