]> git.proxmox.com Git - libgit2.git/blame - tests-clar/filter/custom.c
Port tests from PR 1683
[libgit2.git] / tests-clar / filter / custom.c
CommitLineData
b47349b8
RB
1#include "clar_libgit2.h"
2#include "posix.h"
3#include "blob.h"
4#include "filter.h"
5#include "buf_text.h"
6#include "git2/sys/filter.h"
7#include "git2/sys/repository.h"
8
9#define BITFLIP_FILTER_PRIORITY 20
10#define REVERSE_FILTER_PRIORITY 25
11
12#define VERY_SECURE_ENCRYPTION(b) ((b) ^ 0xff)
13
14#ifdef GIT_WIN32
15# define NEWLINE "\r\n"
16#else
17# define NEWLINE "\n"
18#endif
19
20static char workdir_data[] =
21 "some simple" NEWLINE
22 "data" NEWLINE
23 "that will be" NEWLINE
24 "trivially" NEWLINE
25 "scrambled." NEWLINE;
26
27/* Represents the data above scrambled (bits flipped) after \r\n -> \n
28 * conversion, then bytewise reversed
29 */
30static unsigned char bitflipped_and_reversed_data[] =
31 { 0xf5, 0xd1, 0x9b, 0x9a, 0x93, 0x9d, 0x92, 0x9e, 0x8d, 0x9c, 0x8c,
32 0xf5, 0x86, 0x93, 0x93, 0x9e, 0x96, 0x89, 0x96, 0x8d, 0x8b, 0xf5,
33 0x9a, 0x9d, 0xdf, 0x93, 0x93, 0x96, 0x88, 0xdf, 0x8b, 0x9e, 0x97,
34 0x8b, 0xf5, 0x9e, 0x8b, 0x9e, 0x9b, 0xf5, 0x9a, 0x93, 0x8f, 0x92,
35 0x96, 0x8c, 0xdf, 0x9a, 0x92, 0x90, 0x8c };
36
37#define BITFLIPPED_AND_REVERSED_DATA_LEN 51
38
39static git_repository *g_repo = NULL;
40
41static void register_custom_filters(void);
42
43void test_filter_custom__initialize(void)
44{
45 register_custom_filters();
46
47 g_repo = cl_git_sandbox_init("empty_standard_repo");
48
49 cl_git_mkfile(
50 "empty_standard_repo/.gitattributes",
51 "hero* bitflip reverse\n"
52 "herofile text\n"
53 "heroflip -reverse\n");
54}
55
56void test_filter_custom__cleanup(void)
57{
58 cl_git_sandbox_cleanup();
59 g_repo = NULL;
60}
61
62static int bitflip_filter_apply(
63 git_filter *self,
64 void **payload,
65 git_buf *to,
66 const git_buf *from,
67 const git_filter_source *source)
68{
69 const unsigned char *src = (const unsigned char *)from->ptr;
70 unsigned char *dst;
71 size_t i;
72
73 GIT_UNUSED(self); GIT_UNUSED(payload);
74
75 /* verify that attribute path match worked as expected */
76 cl_assert_equal_i(
77 0, git__strncmp("hero", git_filter_source_path(source), 4));
78
79 if (!from->size)
80 return 0;
81
82 cl_git_pass(git_buf_grow(to, from->size));
83
84 dst = (unsigned char *)to->ptr;
85
86 for (i = 0; i < from->size; i++)
87 dst[i] = VERY_SECURE_ENCRYPTION(src[i]);
88
89 to->size = from->size;
90
91 return 0;
92}
93
94static void bitflip_filter_free(git_filter *f)
95{
96 git__free(f);
97}
98
99static git_filter *create_bitflip_filter(void)
100{
101 git_filter *filter = git__calloc(1, sizeof(git_filter));
102 cl_assert(filter);
103
104 filter->version = GIT_FILTER_VERSION;
105 filter->attributes = "+bitflip";
106 filter->shutdown = bitflip_filter_free;
107 filter->apply = bitflip_filter_apply;
108
109 return filter;
110}
111
112
113static int reverse_filter_apply(
114 git_filter *self,
115 void **payload,
116 git_buf *to,
117 const git_buf *from,
118 const git_filter_source *source)
119{
120 const unsigned char *src = (const unsigned char *)from->ptr;
121 const unsigned char *end = src + from->size;
122 unsigned char *dst;
123
124 GIT_UNUSED(self); GIT_UNUSED(payload); GIT_UNUSED(source);
125
126 /* verify that attribute path match worked as expected */
127 cl_assert_equal_i(
128 0, git__strncmp("hero", git_filter_source_path(source), 4));
129
130 if (!from->size)
131 return 0;
132
133 cl_git_pass(git_buf_grow(to, from->size));
134
135 dst = (unsigned char *)to->ptr + from->size - 1;
136
137 while (src < end)
138 *dst-- = *src++;
139
140 to->size = from->size;
141
142 return 0;
143}
144
145static void reverse_filter_free(git_filter *f)
146{
147 git__free(f);
148}
149
150static git_filter *create_reverse_filter(void)
151{
152 git_filter *filter = git__calloc(1, sizeof(git_filter));
153 cl_assert(filter);
154
155 filter->version = GIT_FILTER_VERSION;
156 filter->attributes = "+reverse";
157 filter->shutdown = reverse_filter_free;
158 filter->apply = reverse_filter_apply;
159
160 return filter;
161}
162
163static void register_custom_filters(void)
164{
165 static int filters_registered = 0;
166
167 if (!filters_registered) {
168 cl_git_pass(git_filter_register(
169 "bitflip", create_bitflip_filter(), BITFLIP_FILTER_PRIORITY));
170
171 cl_git_pass(git_filter_register(
172 "reverse", create_reverse_filter(), REVERSE_FILTER_PRIORITY));
173
174 filters_registered = 1;
175 }
176}
177
178
179void test_filter_custom__to_odb(void)
180{
181 git_filter_list *fl;
182 git_buf out = { 0 };
183 git_buf in = GIT_BUF_INIT_CONST(workdir_data, strlen(workdir_data));
184
185 cl_git_pass(git_filter_list_load(
186 &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_ODB));
187
188 cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
189
190 cl_assert_equal_i(BITFLIPPED_AND_REVERSED_DATA_LEN, out.size);
191
192 cl_assert_equal_i(
193 0, memcmp(bitflipped_and_reversed_data, out.ptr, out.size));
194
195 git_filter_list_free(fl);
196 git_buf_free(&out);
197}
198
199void test_filter_custom__to_workdir(void)
200{
201 git_filter_list *fl;
202 git_buf out = { 0 };
203 git_buf in = GIT_BUF_INIT_CONST(
204 bitflipped_and_reversed_data, BITFLIPPED_AND_REVERSED_DATA_LEN);
205
206 cl_git_pass(git_filter_list_load(
207 &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE));
208
209 cl_git_pass(git_filter_list_apply_to_data(&out, fl, &in));
210
211 cl_assert_equal_i(strlen(workdir_data), out.size);
212
213 cl_assert_equal_i(
214 0, memcmp(workdir_data, out.ptr, out.size));
215
216 git_filter_list_free(fl);
217 git_buf_free(&out);
218}
219
220void test_filter_custom__can_register_a_custom_filter_in_the_repository(void)
221{
222 git_filter_list *fl;
223
224 cl_git_pass(git_filter_list_load(
225 &fl, g_repo, NULL, "herofile", GIT_FILTER_TO_WORKTREE));
226 /* expect: bitflip, reverse, crlf */
227 cl_assert_equal_sz(3, git_filter_list_length(fl));
228 git_filter_list_free(fl);
229
230 cl_git_pass(git_filter_list_load(
231 &fl, g_repo, NULL, "herocorp", GIT_FILTER_TO_WORKTREE));
232 /* expect: bitflip, reverse */
233 cl_assert_equal_sz(2, git_filter_list_length(fl));
234 git_filter_list_free(fl);
235
236 cl_git_pass(git_filter_list_load(
237 &fl, g_repo, NULL, "heroflip", GIT_FILTER_TO_WORKTREE));
238 /* expect: bitflip (because of -reverse) */
239 cl_assert_equal_sz(1, git_filter_list_length(fl));
240 git_filter_list_free(fl);
241
242 cl_git_pass(git_filter_list_load(
243 &fl, g_repo, NULL, "doesntapplytome", GIT_FILTER_TO_WORKTREE));
244 /* expect: none */
245 cl_assert_equal_sz(0, git_filter_list_length(fl));
246 git_filter_list_free(fl);
247}