]> git.proxmox.com Git - libgit2.git/blob - tests/patch/parse.c
a3c4c6730b4dcea76a2f890e8cf3c6887bc1f1c0
[libgit2.git] / tests / patch / parse.c
1 #include "clar_libgit2.h"
2 #include "patch.h"
3 #include "patch_parse.h"
4
5 #include "patch_common.h"
6
7 static void ensure_patch_validity(git_patch *patch)
8 {
9 const git_diff_delta *delta;
10 char idstr[GIT_OID_HEXSZ+1] = {0};
11
12 cl_assert((delta = git_patch_get_delta(patch)) != NULL);
13 cl_assert_equal_i(2, delta->nfiles);
14
15 cl_assert_equal_s(delta->old_file.path, "file.txt");
16 cl_assert(delta->old_file.mode == GIT_FILEMODE_BLOB);
17 cl_assert_equal_i(7, delta->old_file.id_abbrev);
18 git_oid_nfmt(idstr, delta->old_file.id_abbrev, &delta->old_file.id);
19 cl_assert_equal_s(idstr, "9432026");
20 cl_assert_equal_i(0, delta->old_file.size);
21
22 cl_assert_equal_s(delta->new_file.path, "file.txt");
23 cl_assert(delta->new_file.mode == GIT_FILEMODE_BLOB);
24 cl_assert_equal_i(7, delta->new_file.id_abbrev);
25 git_oid_nfmt(idstr, delta->new_file.id_abbrev, &delta->new_file.id);
26 cl_assert_equal_s(idstr, "cd8fd12");
27 cl_assert_equal_i(0, delta->new_file.size);
28 }
29
30 static void ensure_identical_patch_inout(const char *content)
31 {
32 git_buf buf = GIT_BUF_INIT;
33 git_patch *patch;
34
35 cl_git_pass(git_patch_from_buffer(&patch, content, strlen(content), NULL));
36 cl_git_pass(git_patch_to_buf(&buf, patch));
37 cl_assert_equal_strn(buf.ptr, content, strlen(content));
38
39 git_patch_free(patch);
40 git_buf_dispose(&buf);
41 }
42
43 void test_patch_parse__original_to_change_middle(void)
44 {
45 git_patch *patch;
46
47 cl_git_pass(git_patch_from_buffer(
48 &patch, PATCH_ORIGINAL_TO_CHANGE_MIDDLE,
49 strlen(PATCH_ORIGINAL_TO_CHANGE_MIDDLE), NULL));
50 ensure_patch_validity(patch);
51 git_patch_free(patch);
52 }
53
54 void test_patch_parse__leading_and_trailing_garbage(void)
55 {
56 git_patch *patch;
57 const char *leading = "This is some leading garbage.\n"
58 "Maybe it's email headers?\n"
59 "\n"
60 PATCH_ORIGINAL_TO_CHANGE_MIDDLE;
61 const char *trailing = PATCH_ORIGINAL_TO_CHANGE_MIDDLE
62 "\n"
63 "This is some trailing garbage.\n"
64 "Maybe it's an email signature?\n";
65 const char *both = "Here's some leading garbage\n"
66 PATCH_ORIGINAL_TO_CHANGE_MIDDLE
67 "And here's some trailing.\n";
68
69 cl_git_pass(git_patch_from_buffer(&patch, leading, strlen(leading),
70 NULL));
71 ensure_patch_validity(patch);
72 git_patch_free(patch);
73
74 cl_git_pass(git_patch_from_buffer(&patch, trailing, strlen(trailing),
75 NULL));
76 ensure_patch_validity(patch);
77 git_patch_free(patch);
78
79 cl_git_pass(git_patch_from_buffer(&patch, both, strlen(both),
80 NULL));
81 ensure_patch_validity(patch);
82 git_patch_free(patch);
83 }
84
85 void test_patch_parse__nonpatches_fail_with_notfound(void)
86 {
87 git_patch *patch;
88
89 cl_git_fail_with(GIT_ENOTFOUND,
90 git_patch_from_buffer(&patch, PATCH_NOT_A_PATCH,
91 strlen(PATCH_NOT_A_PATCH), NULL));
92 }
93
94 void test_patch_parse__invalid_patches_fails(void)
95 {
96 git_patch *patch;
97
98 cl_git_fail_with(GIT_ERROR,
99 git_patch_from_buffer(&patch, PATCH_CORRUPT_GIT_HEADER,
100 strlen(PATCH_CORRUPT_GIT_HEADER), NULL));
101 cl_git_fail_with(GIT_ERROR,
102 git_patch_from_buffer(&patch,
103 PATCH_CORRUPT_MISSING_NEW_FILE,
104 strlen(PATCH_CORRUPT_MISSING_NEW_FILE), NULL));
105 cl_git_fail_with(GIT_ERROR,
106 git_patch_from_buffer(&patch,
107 PATCH_CORRUPT_MISSING_OLD_FILE,
108 strlen(PATCH_CORRUPT_MISSING_OLD_FILE), NULL));
109 cl_git_fail_with(GIT_ERROR,
110 git_patch_from_buffer(&patch, PATCH_CORRUPT_NO_CHANGES,
111 strlen(PATCH_CORRUPT_NO_CHANGES), NULL));
112 cl_git_fail_with(GIT_ERROR,
113 git_patch_from_buffer(&patch,
114 PATCH_CORRUPT_MISSING_HUNK_HEADER,
115 strlen(PATCH_CORRUPT_MISSING_HUNK_HEADER), NULL));
116 }
117
118 void test_patch_parse__no_newline_at_end_of_new_file(void)
119 {
120 ensure_identical_patch_inout(PATCH_APPEND_NO_NL);
121 }
122
123 void test_patch_parse__no_newline_at_end_of_old_file(void)
124 {
125 ensure_identical_patch_inout(PATCH_APPEND_NO_NL_IN_OLD_FILE);
126 }
127
128 void test_patch_parse__files_with_whitespaces_succeeds(void)
129 {
130 ensure_identical_patch_inout(PATCH_NAME_WHITESPACE);
131 }
132
133 void test_patch_parse__lifetime_of_patch_does_not_depend_on_buffer(void)
134 {
135 git_str diff = GIT_STR_INIT;
136 git_buf rendered = GIT_BUF_INIT;
137 git_patch *patch;
138
139 cl_git_pass(git_str_sets(&diff, PATCH_ORIGINAL_TO_CHANGE_MIDDLE));
140 cl_git_pass(git_patch_from_buffer(&patch, diff.ptr, diff.size, NULL));
141 git_str_dispose(&diff);
142
143 cl_git_pass(git_patch_to_buf(&rendered, patch));
144 cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr);
145 git_buf_dispose(&rendered);
146
147 cl_git_pass(git_patch_to_buf(&rendered, patch));
148 cl_assert_equal_s(PATCH_ORIGINAL_TO_CHANGE_MIDDLE, rendered.ptr);
149 git_buf_dispose(&rendered);
150
151 git_patch_free(patch);
152 }
153
154 void test_patch_parse__binary_file_with_missing_paths(void)
155 {
156 git_patch *patch;
157 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_MISSING_PATHS,
158 strlen(PATCH_BINARY_FILE_WITH_MISSING_PATHS), NULL));
159 }
160
161 void test_patch_parse__binary_file_with_whitespace_paths(void)
162 {
163 git_patch *patch;
164 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS,
165 strlen(PATCH_BINARY_FILE_WITH_WHITESPACE_PATHS), NULL));
166 }
167
168 void test_patch_parse__binary_file_with_empty_quoted_paths(void)
169 {
170 git_patch *patch;
171 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_QUOTED_EMPTY_PATHS,
172 strlen(PATCH_BINARY_FILE_WITH_QUOTED_EMPTY_PATHS), NULL));
173 }
174
175 void test_patch_parse__binary_file_path_with_spaces(void)
176 {
177 git_patch *patch;
178 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITH_SPACES,
179 strlen(PATCH_BINARY_FILE_PATH_WITH_SPACES), NULL));
180 }
181
182 void test_patch_parse__binary_file_path_without_body_paths(void)
183 {
184 git_patch *patch;
185 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS,
186 strlen(PATCH_BINARY_FILE_PATH_WITHOUT_BODY_PATHS), NULL));
187 }
188
189 void test_patch_parse__binary_file_with_truncated_delta(void)
190 {
191 git_patch *patch;
192 cl_git_fail(git_patch_from_buffer(&patch, PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA,
193 strlen(PATCH_BINARY_FILE_WITH_TRUNCATED_DELTA), NULL));
194 cl_assert_equal_s(git_error_last()->message, "truncated binary data at line 5");
195 }
196
197 void test_patch_parse__memory_leak_on_multiple_paths(void)
198 {
199 git_patch *patch;
200 cl_git_fail(git_patch_from_buffer(&patch, PATCH_MULTIPLE_OLD_PATHS, strlen(PATCH_MULTIPLE_OLD_PATHS), NULL));
201 }
202
203 void test_patch_parse__truncated_no_newline_at_end_of_file(void)
204 {
205 size_t len = strlen(PATCH_APPEND_NO_NL) - strlen("at end of file\n");
206 const git_diff_line *line;
207 git_patch *patch;
208
209 cl_git_pass(git_patch_from_buffer(&patch, PATCH_APPEND_NO_NL, len, NULL));
210 cl_git_pass(git_patch_get_line_in_hunk(&line, patch, 0, 4));
211 cl_assert_equal_s(line->content, "\\ No newline ");
212
213 git_patch_free(patch);
214 }
215
216 void test_patch_parse__line_number_overflow(void)
217 {
218 git_patch *patch;
219 cl_git_fail(git_patch_from_buffer(&patch, PATCH_INTMAX_NEW_LINES, strlen(PATCH_INTMAX_NEW_LINES), NULL));
220 git_patch_free(patch);
221 }