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

Re: [PATCH] fmt-merge-msg: avoid leaking strbuf in shortlog()

From
René Scharfe <l.s.r@web.de>
Date
Dec 18, 2017, 19:18 UTC
Message-ID
<f1584860-d0d6-db82-0a49-021924c3e2b7@web.de>
In-Reply-To
<20171208212832.GC7355@sigill.intra.peff.net>
Am 08.12.2017 um 22:28 schrieb Jeff King:
Show 26 quoted lines
> On Fri, Dec 08, 2017 at 10:37:08AM -0800, Junio C Hamano wrote:
> 
>>> The two modes (dup/nodup) make string_list code tricky.  Not sure
>>> how far we'd get with something simpler (e.g. an array of char pointers),
>>> but having the caller do all string allocations would make the code
>>> easier to analyze.
>>
>> Yes.
>>
>> It probably would have been more sensible if the API did not have
>> two modes (instead, have the caller pass whatever string to be
>> stored, *and* make the caller responsible for freeing them *if* it
>> passed an allocated string).
> 
> I'd actually argue the other way: the simplest interface is one where
> the string list owns all of its pointers. That keeps the
> ownership/lifetime issues clear, and it's one less step for the caller
> to have to remember to do at the end (they do have to clear() the list,
> but they must do that anyway to free the array of items).
> 
> It does mean that some callers may have to remember to free a temporary
> buffer right after adding its contents to the list. But that's a lesser
> evil, I think, since the memory ownership issues are all clearly
> resolved at the time of add.
> 
> The big cost is just extra copies/allocations.
An interface requiring callers to allocate can be used to implement a
wrapper that does all allocations for them -- the other way around is
harder.  It can be used to avoid object duplication, but duplicates
functions.  No idea if that's worth it.
 
Show 36 quoted lines
>> For the push_refs_with_push() patch you sent, another possible fix
>> would be to make cas_options a nodup kind so that the result of
>> strbuf_detach() does not get an extra strdup to be lost when placed
>> in cas_options.  With the current string-list API that would not
>> quite work, because freeing done in _release() is tied to the
>> "dup/nodup" ness of the string list.  I think there even is a
>> codepath that initializes a string_list as nodup kind, stuffs string
>> in it giving the ownership, and then flips it into dup kind just
>> before calling _release() only to have it free the strings, or
>> something silly/ugly like that.
> 
> Yes, the first grep hit for NODUP is bisect_clean_state(), which does
> this. I think it would be more clear if we could do:
> 
> diff --git a/bisect.c b/bisect.c
> index 0fca17c02b..7c59408a13 100644
> --- a/bisect.c
> +++ b/bisect.c
> @@ -1060,8 +1060,7 @@ static int mark_for_removal(const char *refname, const struct object_id *oid,
>   			    int flag, void *cb_data)
>   {
>   	struct string_list *refs = cb_data;
> -	char *ref = xstrfmt("refs/bisect%s", refname);
> -	string_list_append(refs, ref);
> +	string_list_appendf(refs, "refs/bisect%s", refname);
>   	return 0;
>   }
>   
> @@ -1070,11 +1069,10 @@ int bisect_clean_state(void)
>   	int result = 0;
>   
>   	/* There may be some refs packed during bisection */
> -	struct string_list refs_for_removal = STRING_LIST_INIT_NODUP;
> +	struct string_list refs_for_removal = STRING_LIST_INIT_DUP;
>   	for_each_ref_in("refs/bisect", mark_for_removal, (void *) &refs_for_removal);
>   	string_list_append(&refs_for_removal, xstrdup("BISECT_HEAD"));
The xstrdup() here would have to go.
Show 10 quoted lines
>   	result = delete_refs("bisect: remove", &refs_for_removal, REF_NO_DEREF);
> -	refs_for_removal.strdup_strings = 1;
>   	string_list_clear(&refs_for_removal, 0);
>   	unlink_or_warn(git_path_bisect_expected_rev());
>   	unlink_or_warn(git_path_bisect_ancestors_ok());
> 
> 
> Having a "format into a string" wrapper doesn't cover _every_ string you
> might want to add to a list, but my experience with argv_array_pushf
> leads me to believe that it covers quite a lot of cases.

It would fit in with the rest of the API -- we have string_list_append() as a wrapper for string_list_append_nodup()+xstrdup() already. We also have similar functions for strbuf and argv_array. I find it a bit sad to reimplement xstrfmt() yet again instead of using it directly, though.

René
Previous: Jeff KingNext: Jeff King
Message 12 of 16 in “fmt-merge-msg: avoid leaking strbuf in shortlog()”
  1. fmt-merge-msg: avoid leaking strbuf in shortlog()René Scharfe, Dec 7, 2017
  2. Jeff KingDec 7, 2017
  3. René ScharfeDec 8, 2017
  4. Junio C HamanoDec 8, 2017
  5. René ScharfeDec 8, 2017
  6. Jeff KingDec 8, 2017
  7. Junio C HamanoDec 7, 2017
  8. Jeff KingDec 8, 2017
  9. René ScharfeDec 8, 2017
  10. Junio C HamanoDec 8, 2017
  11. Jeff KingDec 8, 2017
  12. René ScharfeDec 18, 2017
  13. Jeff KingDec 19, 2017
  14. René ScharfeDec 19, 2017
  15. Jeff KingDec 20, 2017
  16. Jeff KingDec 8, 2017

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.