- Use a strbuf instead of a fixed-size buffer - Free the argv_array when we're done with it
Note that since write_archive modifies the argv array passed to it we copy the argv_array values into a new array of char* and then free the original argv_array structure and the new array without worrying about what the values now look like. Signed-off-by: John Keeping <[email protected]> --- Changes since v1: - Fix freeing the argv array to avoid double frees. ui-snapshot.c | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/ui-snapshot.c b/ui-snapshot.c index a47884e..1b361c1 100644 --- a/ui-snapshot.c +++ b/ui-snapshot.c @@ -15,14 +15,33 @@ static int write_archive_type(const char *format, const char *hex, const char *prefix) { struct argv_array argv = ARGV_ARRAY_INIT; + const char **nargv; + int result; argv_array_push(&argv, "snapshot"); argv_array_push(&argv, format); if (prefix) { + struct strbuf buf = STRBUF_INIT; + strbuf_addstr(&buf, prefix); + strbuf_addch(&buf, '/'); argv_array_push(&argv, "--prefix"); - argv_array_push(&argv, fmt("%s/", prefix)); + argv_array_push(&argv, buf.buf); + strbuf_release(&buf); } argv_array_push(&argv, hex); - return write_archive(argv.argc, argv.argv, NULL, 1, NULL, 0); + /* + * Now we need to copy the pointers to arguments into a new + * structure because write_archive will rearrange its arguments + * which may result in duplicated/missing entries causing leaks + * or double-frees in argv_array_clear. + */ + nargv = xmalloc(sizeof(char *) * (argv.argc + 1)); + /* argv_array guarantees a trailing NULL entry. */ + memcpy(nargv, argv.argv, sizeof(char *) * (argv.argc + 1)); + + result = write_archive(argv.argc, nargv, NULL, 1, NULL, 0); + argv_array_clear(&argv); + free(nargv); + return result; } static int write_tar_archive(const char *hex, const char *prefix) -- 1.8.2.692.g17a9715 _______________________________________________ cgit mailing list [email protected] http://hjemli.net/mailman/listinfo/cgit
