diff options
author | Patrick Steinhardt <ps@pks.im> | 2019-07-05 09:35:43 +0200 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2019-07-05 09:35:43 +0200 |
commit | dedf70ad2b9f3dd5a5b299f64476285653cf62b7 (patch) | |
tree | e9d703ddd8763459141c67138b413d72386ff2b1 /src/patch_parse.c | |
parent | c4c1500a8bc99066cbb4340717d91020c02a75ae (diff) | |
download | libgit2-dedf70ad2b9f3dd5a5b299f64476285653cf62b7.tar.gz |
patch_parse: do not depend on parsed buffer's lifetime
When parsing a patch from a buffer, we let the patch lines point into
the original buffer. While this is efficient use of resources, this also
ties the lifetime of the parsed patch to the parsed buffer. As this
behaviour is not documented anywhere in our API it is very surprising to
its users.
Untie the lifetime by duplicating the lines into the parsed patch. Add a
test that verifies that lifetimes are indeed independent of each other.
Diffstat (limited to 'src/patch_parse.c')
-rw-r--r-- | src/patch_parse.c | 6 |
1 files changed, 5 insertions, 1 deletions
diff --git a/src/patch_parse.c b/src/patch_parse.c index b44d4f02f..5e5e5d941 100644 --- a/src/patch_parse.c +++ b/src/patch_parse.c @@ -588,8 +588,8 @@ static int parse_hunk_body( memset(line, 0x0, sizeof(git_diff_line)); - line->content = ctx->parse_ctx.line + prefix; line->content_len = ctx->parse_ctx.line_len - prefix; + line->content = git__strndup(ctx->parse_ctx.line + prefix, line->content_len); line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len; line->origin = origin; line->num_lines = 1; @@ -1038,6 +1038,8 @@ int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx) static void patch_parsed__free(git_patch *p) { git_patch_parsed *patch = (git_patch_parsed *)p; + git_diff_line *line; + size_t i; if (!patch) return; @@ -1047,6 +1049,8 @@ static void patch_parsed__free(git_patch *p) git__free((char *)patch->base.binary.old_file.data); git__free((char *)patch->base.binary.new_file.data); git_array_clear(patch->base.hunks); + git_array_foreach(patch->base.lines, i, line) + git__free((char *) line->content); git_array_clear(patch->base.lines); git__free(patch->base.delta); |