Skip to content

Commit f33ca47

Browse files
authored
Merge pull request libgit2#5158 from pks-t/pks/patch-parsed-lifetime
patch_parse: do not depend on parsed buffer's lifetime
2 parents d78a1b1 + dedf70a commit f33ca47

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

src/patch_parse.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -588,8 +588,8 @@ static int parse_hunk_body(
588588

589589
memset(line, 0x0, sizeof(git_diff_line));
590590

591-
line->content = ctx->parse_ctx.line + prefix;
592591
line->content_len = ctx->parse_ctx.line_len - prefix;
592+
line->content = git__strndup(ctx->parse_ctx.line + prefix, line->content_len);
593593
line->content_offset = ctx->parse_ctx.content_len - ctx->parse_ctx.remain_len;
594594
line->origin = origin;
595595
line->num_lines = 1;
@@ -1038,6 +1038,8 @@ int git_patch_parsed_from_diff(git_patch **out, git_diff *d, size_t idx)
10381038
static void patch_parsed__free(git_patch *p)
10391039
{
10401040
git_patch_parsed *patch = (git_patch_parsed *)p;
1041+
git_diff_line *line;
1042+
size_t i;
10411043

10421044
if (!patch)
10431045
return;
@@ -1047,6 +1049,8 @@ static void patch_parsed__free(git_patch *p)
10471049
git__free((char *)patch->base.binary.old_file.data);
10481050
git__free((char *)patch->base.binary.new_file.data);
10491051
git_array_clear(patch->base.hunks);
1052+
git_array_foreach(patch->base.lines, i, line)
1053+
git__free((char *) line->content);
10501054
git_array_clear(patch->base.lines);
10511055
git__free(patch->base.delta);
10521056

tests/patch/parse.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,3 +108,23 @@ void test_patch_parse__files_with_whitespaces_succeeds(void)
108108
cl_git_pass(git_patch_from_buffer(&patch, PATCH_NAME_WHITESPACE, strlen(PATCH_NAME_WHITESPACE), NULL));
109109
git_patch_free(patch);
110110
}
111+
112+
void test_patch_parse__lifetime_of_patch_does_not_depend_on_buffer(void)
113+
{
114+
git_buf diff = GIT_BUF_INIT, rendered = GIT_BUF_INIT;
115+
git_patch *patch;
116+
117+
cl_git_pass(git_buf_sets(&diff, PATCH_ORIGINAL_TO_CHANGE_MIDDLE));
118+
cl_git_pass(git_patch_from_buffer(&patch, diff.ptr, diff.size, NULL));
119+
git_buf_dispose(&diff);
120+
121+
cl_git_pass(git_patch_to_buf(&rendered, patch));
122+
cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr);
123+
git_buf_dispose(&rendered);
124+
125+
cl_git_pass(git_patch_to_buf(&rendered, patch));
126+
cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr);
127+
git_buf_dispose(&rendered);
128+
129+
git_patch_free(patch);
130+
}

0 commit comments

Comments
 (0)