threads / patch / 40621

patch, 2 partsread_branches_file: plug a FILE* leak

Subject: [PATCH 1/2 jk/war-on-sprintf] read_branches_file: plug a FILE* leak

## tl;dr

5 messages between Oct 23, 2015 and Oct 23, 2015. Diffs are folded; open one to read it.

replies: 4people: 3as markdown or json

Johannes Sixt· Oct 23, 2015, 06:02 UTC · lore

The earlier rewrite f28e3ab2 (read_branches_file: simplify string handling) of read_branches_file() lost an fclose() call. Put it back.

As on Windows files that are open cannot be removed, the leak manifests in a failure of 'git remote rename origin origin' when the remote's URL is specified in .git/branches/origin, because by the time that the command attempts to remove this file, it is still open.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
 remote.c | 1 +
 1 file changed, 1 insertion(+)
Show changes to remote.c +1 −0
diff --git a/remote.c b/remote.c
index 1101f82..fb16153 100644
--- a/remote.c
+++ b/remote.c
@@ -282,6 +282,7 @@ static void read_branches_file(struct remote *remote)
 		return;
 
 	strbuf_getline(&buf, f, '\n');
+	fclose(f);
 	strbuf_trim(&buf);
 	if (!buf.len) {
 		strbuf_release(&buf);
-- 
2.3.2.245.gb5bf9d3
Johannes Sixt· Oct 23, 2015, 06:02 UTC · re: Johannes Sixt · lore

[PATCH 2/2 jk/war-on-sprintf] compat/mingw.c: remove printf format warning

5096d490 (convert trivial sprintf / strcpy calls to xsnprintf) converted two sprintf calls. Now GCC warns that "format '%u' expects argument of type 'unsigned int', but argument 4 has type 'long unsigned int'". Instead of changing the format string, use a variable of type unsigned in place of the typedef-ed type DWORD, which hides that it is actually an unsigned long.

There is no correctness issue with the old code because unsigned long and unsigned are always of the same size on Windows, even in 64-bit builds.

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
---
I do not know why there are no warnings with the old code. Apparently, the
system provided sprintf declaration does not have format-printf
annotation.
 compat/mingw.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Show changes to compat/mingw.c +1 −1
diff --git a/compat/mingw.c b/compat/mingw.c
index a168800..90bdb1e 100644
--- a/compat/mingw.c
+++ b/compat/mingw.c
@@ -2131,7 +2131,7 @@ void mingw_startup()
 
 int uname(struct utsname *buf)
 {
-	DWORD v = GetVersion();
+	unsigned v = (unsigned)GetVersion();
 	memset(buf, 0, sizeof(*buf));
 	xsnprintf(buf->sysname, sizeof(buf->sysname), "Windows");
 	xsnprintf(buf->release, sizeof(buf->release),
-- 
2.3.2.245.gb5bf9d3
Jeff King· Oct 23, 2015, 11:20 UTC · re: Johannes Sixt · lore

Re: [PATCH 2/2 jk/war-on-sprintf] compat/mingw.c: remove printf format warning

On Fri, Oct 23, 2015 at 08:02:52AM +0200, Johannes Sixt wrote:
Show 15 quoted lines
> 5096d490 (convert trivial sprintf / strcpy calls to xsnprintf) converted
> two sprintf calls. Now GCC warns that "format '%u' expects argument of
> type 'unsigned int', but argument 4 has type 'long unsigned int'".
> Instead of changing the format string, use a variable of type unsigned
> in place of the typedef-ed type DWORD, which hides that it is actually an
> unsigned long.
> 
> There is no correctness issue with the old code because unsigned long and
> unsigned are always of the same size on Windows, even in 64-bit builds.
> 
> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
> ---
> I do not know why there are no warnings with the old code. Apparently, the
> system provided sprintf declaration does not have format-printf
> annotation.
Makes sense, and the patch looks obviously correct.
-Peff
Jeff King· Oct 23, 2015, 11:19 UTC · re: Johannes Sixt · lore

Re: [PATCH 1/2 jk/war-on-sprintf] read_branches_file: plug a FILE* leak

On Fri, Oct 23, 2015 at 08:02:51AM +0200, Johannes Sixt wrote:
Show 7 quoted lines
> The earlier rewrite f28e3ab2 (read_branches_file: simplify string handling)
> of read_branches_file() lost an fclose() call. Put it back.
> 
> As on Windows files that are open cannot be removed, the leak manifests in
> a failure of 'git remote rename origin origin' when the remote's URL is
> specified in .git/branches/origin, because by the time that the command
> attempts to remove this file, it is still open.

Thanks for catching. This was due to my last-minute rewrite of strbuf_read_file into fopen/strbuf_getline. Your patch looks good to me.

-Peff
Junio C Hamano· Oct 23, 2015, 17:18 UTC · re: Johannes Sixt · lore

Re: [PATCH 1/2 jk/war-on-sprintf] read_branches_file: plug a FILE* leak

Johannes Sixt <j6t@kdbg.org> writes:
Show 10 quoted lines
> The earlier rewrite f28e3ab2 (read_branches_file: simplify string handling)
> of read_branches_file() lost an fclose() call. Put it back.
>
> As on Windows files that are open cannot be removed, the leak manifests in
> a failure of 'git remote rename origin origin' when the remote's URL is
> specified in .git/branches/origin, because by the time that the command
> attempts to remove this file, it is still open.
>
> Signed-off-by: Johannes Sixt <j6t@kdbg.org>
> ---
Thanks (and also for 2/2).
Show 15 quoted lines
>  remote.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/remote.c b/remote.c
> index 1101f82..fb16153 100644
> --- a/remote.c
> +++ b/remote.c
> @@ -282,6 +282,7 @@ static void read_branches_file(struct remote *remote)
>  		return;
>  
>  	strbuf_getline(&buf, f, '\n');
> +	fclose(f);
>  	strbuf_trim(&buf);
>  	if (!buf.len) {
>  		strbuf_release(&buf);

← back to recent threads