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

Re: [PATCH v3 2/2] diff: add -I<regex> that ignores matching changes

From
Junio C Hamano <gitster@pobox.com>
Date
Oct 16, 2020, 18:04 UTC
Message-ID
<xmqqeelycajx.fsf@gitster.c.googlers.com>
In-Reply-To
<afd3b1cf-b883-6df5-bea5-28f8e06d8702@gmail.com>
Phillip Wood <phillip.wood123@gmail.com> writes:
Show 17 quoted lines
>> @@ -6405,6 +6428,11 @@ void diff_flush(struct diff_options *options)
>>   	DIFF_QUEUE_CLEAR(q);
>>   	if (options->close_file)
>>   		fclose(options->file);
>> +	for (i = 0; i < options->ignore_regex_nr; i++) {
>> +		regfree(options->ignore_regex[i]);
>> +		free(options->ignore_regex[i]);
>> +	}
>> +	free(options->ignore_regex);
>
> If I run `git log -p -I foo` then the address sanitizer reports
>
> AddressSanitizer: heap-use-after-free xdiff/xdiffi.c:1027 in
> record_matches_regex
>
> after it has printed the diff for the first commit. I think freeing
> the regex here is the cause of the problem.

Yes, this is a good location to clear the diff_queue, which is per-invocation. But diff_options->ignore_regex[] can and should be shared across multiple invocations of the diff machinery, as we are parsing upfront in the command line option parser just once to be used throughout the life of the program. It is wrong to free them early like this.

I really hate to suggest this, one common API call made into the diff machinery from various consumers, when they are absolutely done with diff_options, is probably diff_result_code(). Its purpose is to collect bits computed to participate in the overall result into the final result code and anybody who ran one or more diff and wants to learn the outcome must call it, so it is unlikely that callers that matter are missing a call to finalize their uses of the diff machinery. So if freeing .ignore_regex[] is really necessary, it could be used to tell us where to do so [*1*].

Unlike per-invocation resources that MUST be freed for repeated invocations of the diff machinery made in "git log" family, resources held for and repeatedly used during the entire session like this may not have to be freed, to be honest, though.

Thanks.
[Footnote]
*1* Adding calls to free() in diff_result_code() directly is
    probably not a good idea.  Some callers may not even need result
    code (e.g.  "blame") and do not call it at all, but we may want
    to free the resource in diff_options that is not per-invocation.
    So if we were to do this, we probably need a new API function,
    perhaps diff_options_clear() or something, and call that from
    diff_result_code(), and then find callers that do not care about
    the result code and call diff_options_clear() directly from
    them.
    If a caller does a single diff_setup_done(), makes repeated
    calls to the diff machinery, and calls diff_result_code() once
    per each iteration (e.g. imagine "git log -p" that detects the
    status for each commit), then having the diff_options_clear()
    call in diff_result_code() will break the machinery, so if we
    were to follow the outline given in the previous paragraph, we
    need to make sure there is no such caller.  But I see that
    diff_result_code() does not clear the fields it looks at in the
    diff_options fields after it uses them, so the second and
    subsequent calls into the diff machinery by such a caller may
    already be broken (not in the "resource leakage" sense, but in
    the correctness sense).
    
Previous: Phillip WoodNext: Michał Kępień
Message 40 of 57 in “diff: add -I<regex> that ignores matching changes”
  1. 0/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 1, 2020
  2. 2/2 t: add -I<regex> testsMichał Kępień, Oct 1, 2020
  3. 1/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 1, 2020
  4. Junio C HamanoOct 1, 2020
  5. Michał KępieńOct 7, 2020
  6. Junio C HamanoOct 7, 2020
  7. Junio C HamanoOct 1, 2020
  8. 0/3 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 12, 2020
  9. 1/3 merge-base, xdiff: zero out xpparam_t structuresMichał Kępień, Oct 12, 2020
  10. Johannes SchindelinOct 12, 2020
  11. Junio C HamanoOct 12, 2020
  12. Junio C HamanoOct 12, 2020
  13. Michał KępieńOct 13, 2020
  14. 2/3 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 12, 2020
  15. Johannes SchindelinOct 12, 2020
  16. Junio C HamanoOct 12, 2020
  17. Johannes SchindelinOct 12, 2020
  18. Junio C HamanoOct 12, 2020
  19. Michał KępieńOct 13, 2020
  20. Junio C HamanoOct 13, 2020
  21. Michał KępieńOct 13, 2020
  22. Johannes SchindelinOct 13, 2020
  23. Junio C HamanoOct 13, 2020
  24. Michał KępieńOct 13, 2020
  25. Junio C HamanoOct 12, 2020
  26. Michał KępieńOct 13, 2020
  27. Junio C HamanoOct 12, 2020
  28. Michał KępieńOct 13, 2020
  29. 3/3 t: add -I<regex> testsMichał Kępień, Oct 12, 2020
  30. Johannes SchindelinOct 12, 2020
  31. Michał KępieńOct 13, 2020
  32. Johannes SchindelinOct 13, 2020
  33. Junio C HamanoOct 13, 2020
  34. Michał KępieńOct 13, 2020
  35. Johannes SchindelinOct 15, 2020
  36. 0/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 15, 2020
  37. 1/2 merge-base, xdiff: zero out xpparam_t structuresMichał Kępień, Oct 15, 2020
  38. 2/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 15, 2020
  39. Phillip WoodOct 16, 2020
  40. Junio C HamanoOct 16, 2020
  41. Michał KępieńOct 19, 2020
  42. Junio C HamanoOct 16, 2020
  43. Michał KępieńOct 19, 2020
  44. Junio C HamanoOct 19, 2020
  45. Johannes SchindelinOct 16, 2020
  46. 0/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 20, 2020
  47. 1/2 merge-base, xdiff: zero out xpparam_t structuresMichał Kępień, Oct 20, 2020
  48. 2/2 diff: add -I<regex> that ignores matching changesMichał Kępień, Oct 20, 2020
  49. 1/2 diff: add an API for deferred freeingÆvar Arnfjörð Bjarmason, Feb 5, 2021
  50. Johannes SchindelinFeb 10, 2021
  51. Ævar Arnfjörð BjarmasonFeb 11, 2021
  52. Johannes SchindelinFeb 11, 2021
  53. Jeff KingFeb 11, 2021
  54. 2/2 diff: plug memory leak from regcomp() on {log,diff} -IÆvar Arnfjörð Bjarmason, Feb 11, 2021
  55. 0/2 diff: add an API for deferred freeingÆvar Arnfjörð Bjarmason, Feb 11, 2021
  56. 1/2 diff: add an API for deferred freeingÆvar Arnfjörð Bjarmason, Feb 11, 2021
  57. 2/2 diff: plug memory leak from regcomp() on {log,diff} -IÆvar Arnfjörð Bjarmason, Feb 5, 2021

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.