Jeff King wrote: > On Wed, Sep 20, 2017 at 03:48:26PM -0700, Jonathan Nieder wrote: >> Jeff King wrote: >>> Subject: [PATCH] revision: replace "struct cmdline_pathspec" with argv_array >>> >>> We assemble an array of strings in a custom struct, >>> NULL-terminate the result, and then pass it to >>> parse_pathspec(). >>> >>> But then we never free the array or the individual strings >>> (nor can we do the latter, as they are heap-allocated when >>> they come from stdin but not when they come from the >>> passed-in argv). [...] >> Except... is the idea that this allows the strings from stdin to be >> freed sooner, as soon as they have been parsed into a "struct >> pathspec"? > > Well, no...the idea is that this is a function which leaks a bunch of > memory, and we shouldn't have to think hard about how often its leak can > be triggered or how severe it is. We should just fix it. I forgot to say: thanks for writing such a pleasant patch. Reviewed-by: Jonathan Nieder <jrnieder@xxxxxxxxx> [...] > I certainly agree that the pathspec interface could use better > documentation. Patches welcome? :) Here's such a patch. -- 8< -- Subject: pathspec doc: parse_pathspec does not maintain references to args The command line arguments passed to main() are valid for the life of a program, but the same is not true for all other argv-style arrays (e.g. when a caller creates an argv_array). Clarify that parse_pathspec does not rely on the argv passed to it to remain valid. This makes it easier to tell that callers like "git rev-list --stdin" are safe and ensures that that is more likely to remain true as the implementation of parse_pathspec evolves. Signed-off-by: Jonathan Nieder <jrnieder@xxxxxxxxx> --- pathspec.c | 4 ---- pathspec.h | 7 +++++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/pathspec.c b/pathspec.c index e2a23ebc96..cdefdc7cc0 100644 --- a/pathspec.c +++ b/pathspec.c @@ -526,10 +526,6 @@ static void NORETURN unsupported_magic(const char *pattern, pattern, sb.buf); } -/* - * Given command line arguments and a prefix, convert the input to - * pathspec. die() if any magic in magic_mask is used. - */ void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask, unsigned flags, const char *prefix, const char **argv) diff --git a/pathspec.h b/pathspec.h index 60e6500401..6420d1080a 100644 --- a/pathspec.h +++ b/pathspec.h @@ -70,6 +70,13 @@ struct pathspec { */ #define PATHSPEC_LITERAL_PATH (1<<6) +/* + * Given command line arguments and a prefix, convert the input to + * pathspec. die() if any magic in magic_mask is used. + * + * Any arguments used are copied. It is safe for the caller to modify + * or free 'prefix' and 'args' after calling this function. + */ extern void parse_pathspec(struct pathspec *pathspec, unsigned magic_mask, unsigned flags, -- 2.14.1.821.g8fa685d3b7