git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH] builtin/commit.c: convert trivial snprintf calls to xsnprintf

From
Jeff King <peff@peff.net>
Date
Dec 13, 2016, 19:10 UTC
Message-ID
<20161213191046.vbl7st3qf5xxjhab@sigill.intra.peff.net>
In-Reply-To
<xmqqy3zj3b3a.fsf@gitster.mtv.corp.google.com>
On Tue, Dec 13, 2016 at 11:03:53AM -0800, Junio C Hamano wrote:
Show 42 quoted lines
> >> @@ -1525,12 +1526,10 @@ static int git_commit_config(const char *k, const char *v, void *cb)
> >>  static int run_rewrite_hook(const unsigned char *oldsha1,
> >>  			    const unsigned char *newsha1)
> >>  {
> >> -	/* oldsha1 SP newsha1 LF NUL */
> >> -	static char buf[2*40 + 3];
> >> +	char *buf;
> >>  	struct child_process proc = CHILD_PROCESS_INIT;
> >>  	const char *argv[3];
> >>  	int code;
> >> -	size_t n;
> >>  
> >>  	argv[0] = find_hook("post-rewrite");
> >>  	if (!argv[0])
> >> @@ -1546,34 +1545,33 @@ static int run_rewrite_hook(const unsigned char *oldsha1,
> >>  	code = start_command(&proc);
> >>  	if (code)
> >>  		return code;
> >> -	n = snprintf(buf, sizeof(buf), "%s %s\n",
> >> -		     sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
> >> +	buf = xstrfmt("%s %s\n", sha1_to_hex(oldsha1), sha1_to_hex(newsha1));
> >>  	sigchain_push(SIGPIPE, SIG_IGN);
> >> -	write_in_full(proc.in, buf, n);
> >> +	write_in_full(proc.in, buf, strlen(buf));
> >>  	close(proc.in);
> >> +	free(buf);
> >
> > Any time you care about the length of the result, I'd generally use an
> > actual strbuf instead of xstrfmt. The extra strlen isn't a big deal
> > here, but it somehow seems simpler to me. It probably doesn't matter
> > much either way, though.
> 
> Your justification for this extra allocation was that it is a
> heavy-weight operation.  While I agree that the runtime cost of
> allocation and deallocation does not matter, I would be a bit
> worried about extra cognitive burden to programmers.  They did not
> have to worry about leaking because they are writing a fixed length
> string.  Now they do, whether they use xstrfmt() or struct strbuf.
> When they need to update what they write, they do have to remember
> to adjust the size of the "fixed string", and the original is not
> free from the "programmers' cognitive cost" point of view, of
> course.  Probably use of strbuf/xstrfmt is an overall win.
So I think you are agreeing, but I have a minor nit to pick. :)

The fact that the extra allocation will not hurt performance is _necessary_, but not _sufficient_. So it's not a justification in itself, only something we have to check before proceeding.

The only justification here is that magic numbers like "2*40 + 3" are confusing and a potential maintenance burden. And that's why I suggested splitting this one out from the other two (whose justification is "PATH_MAX is sometimes too small").

I agree with you that it's a tradeoff between "magic numbers" versus "having to free resources". In my opinion it's a net improvement, but I think it would also be reasonable to switch to xsnprintf() here. Then the programmer has an automatic check that the buffer size is sufficient.

-Peff
Previous: Junio C Hamano
Message 4 of 4 in “builtin/commit.c: convert trivial snprintf calls to xsnprintf”
  1. builtin/commit.c: convert trivial snprintf calls to xsnprintfElia Pinto, Dec 13, 2016
  2. Jeff KingDec 13, 2016
  3. Junio C HamanoDec 13, 2016
  4. Jeff KingDec 13, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.