Fix another file leak
Hi,
Vigilant Sentry (our C/C++ static analysis tool) found that commit 6d4bb383, added a file leak to builtin/fetch.c.
static int store_updated_refs(...
{
FILE *fp;
...
fp = fopen(filename, "a");
if (!fp)
return error(_("cannot open %s: %s\n"), filename, strerror(errno));
....
if (check_everything_connected(iterate_ref_map, 0, &rm))
return error(_("%s did not send all necessary objects\n"), url);Please close the file handle before returning from the function.
Thanks,
Chris
Signature · 3 lines
Chris Wilson http://vigilantsw.com/ Vigilant Software, LLC
PATCH 1/1 fetch: plug two leaks on error exit in store_updated_refs
Close FETCH_HEAD and release the string url even if we have to leave the function store_updated_refs() early.
--- builtin/fetch.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-)
builtin/fetch.c +6 -2
@@ -379,8 +379,12 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, url =xstrdup ("foreign" ); rm = ref_map; -if (check_everything_connected (iterate_ref_map,0 , &rm)) -return error (_ ("%s did not send all necessary objects\n" ), url); +if (check_everything_connected (iterate_ref_map,0 , &rm)) { +error (_ ("%s did not send all necessary objects\n" ), url); +free (url); +fclose (fp); +return -1 ; + }for (rm = ref_map; rm; rm = rm->next) {struct ref *ref =NULL ;
Signature · 1 line
1.7.7
Re: [PATCH] fetch: plug two leaks on error exit in store_updated_refs
Quoted 20 lines · René Scharfe
builtin/fetch.c +6
-3@@ -379,8 +379,12 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, url = xstrdup("foreign"); rm = ref_map; - if (check_everything_connected(iterate_ref_map, 0, &rm)) - return error(_("%s did not send all necessary objects\n"), url); + if (check_everything_connected(iterate_ref_map, 0, &rm)) { + error(_("%s did not send all necessary objects\n"), url); + free(url); + fclose(fp); + return -1; + } for (rm = ref_map; rm; rm = rm->next) { struct ref *ref = NULL; --
Quoted 1 line
1.7.7
How about reusing the function's cleanup calls, like this?
-- >8 --
builtin/fetch.c +0 -0
@@ -423,8 +423,10 @@ static int store_updated_refs(const char
*raw_url, const char *remote_name,
else
url = xstrdup("foreign");
- if (check_everything_connected(ref_map, 0))
- return error(_("%s did not send all necessary objects\n"), url);
+ if (check_everything_connected(ref_map, 0)) {
+ rc = error(_("%s did not send all necessary objects\n"), url);
+ goto abort;
+ }
for (rm = ref_map; rm; rm = rm->next) {
struct ref *ref = NULL;
@@ -506,12 +508,15 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
fprintf(stderr, " %s\n", note);
}
}
- free(url);
- fclose(fp);
+
if (rc & STORE_REF_ERROR_DF_CONFLICT)
error(_("some local refs could not be updated; try running\n"
" 'git remote prune %s' to remove any old, conflicting " "branches"), remote_name);
+
+abort:
+ free(url);
+ fclose(fp);
return rc;
}
--
Signature · 2 lines
Cheers, Ray Chuan
Re: [PATCH] fetch: plug two leaks on error exit in store_updated_refs
Am 07.10.2011 08:49, schrieb Tay Ray Chuan:
Quoted 1 line
How about reusing the function's cleanup calls, like this?
Yes, that's better.
Quoted 28 lines
-- >8 --
builtin/fetch.c +4
-2@@ -423,8 +423,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, else url = xstrdup("foreign"); -if (check_everything_connected (ref_map,0 )) -return error (_ ("%s did not send all necessary objects\n" ), url); +if (check_everything_connected (ref_map,0 )) { + rc =error (_ ("%s did not send all necessary objects\n" ), url); + goto abort; + }for (rm = ref_map; rm; rm = rm->next) {builtin/fetch.c +1
-2struct ref *ref =NULL ;@@ -506,12 +508,15 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,fprintf (stderr," %s\n" , note); } } -free (url); -fclose (fp); +
builtin/fetch.c static int store_updated_refs(const char · line 522
Quoted 10 lines
builtin/fetch.c +4
-0if (rc &STORE_REF_ERROR_DF_CONFLICT )error (_ ("some local refs could not be updated; try running\n" " 'git remote prune %s' to remove any old, conflicting " "branches" ), remote_name); + +abort: +free (url); +fclose (fp);return rc; }
Micro-nit: If you start the label with a space ("+ abort:") then the code continues to play nice with git grep -W.
René
PATCH v2 1/1 fetch: plug two leaks on error exit in store_updated_refs
Close FETCH_HEAD and release the string url even if we have to leave the function store_updated_refs() early.
--- builtin/fetch.c | 13 +++++++++---- 1 files changed, 9 insertions(+), 4 deletions(-)
builtin/fetch.c +9 -4
@@ -423,8 +423,10 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,else url =xstrdup ("foreign" ); -if (check_everything_connected (ref_map,0 )) -return error (_ ("%s did not send all necessary objects\n" ), url); +if (check_everything_connected (ref_map,0 )) { + rc =error (_ ("%s did not send all necessary objects\n" ), url); + goto abort; + }for (rm = ref_map; rm; rm = rm->next) {struct ref *ref =NULL ;
@@ -506,12 +508,15 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,fprintf (stderr," %s\n" , note); } } -free (url); -fclose (fp); +if (rc &STORE_REF_ERROR_DF_CONFLICT )error (_ ("some local refs could not be updated; try running\n" " 'git remote prune %s' to remove any old, conflicting " "branches" ), remote_name); + + abort: +free (url); +fclose (fp);return rc; }
Signature · 1 line
1.7.7.584.g16d0ea