]> git.proxmox.com Git - libgit2.git/blame - src/filter.c
Merge pull request #2909 from stewid/remove_extra_semicolon
[libgit2.git] / src / filter.c
CommitLineData
44b1ff4c 1/*
359fc2d2 2 * Copyright (C) the libgit2 contributors. All rights reserved.
44b1ff4c
VM
3 *
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
6 */
7
8#include "common.h"
9#include "fileops.h"
10#include "hash.h"
11#include "filter.h"
c5266eba 12#include "repository.h"
0646634e 13#include "global.h"
2a7d224f 14#include "git2/sys/filter.h"
c5266eba 15#include "git2/config.h"
9587895f 16#include "blob.h"
974774c7 17#include "attr_file.h"
2a7d224f 18#include "array.h"
44b1ff4c 19
570ba25c
RB
20struct git_filter_source {
21 git_repository *repo;
22 const char *path;
23 git_oid oid; /* zero if unknown (which is likely) */
24 uint16_t filemode; /* zero if unknown */
2a7d224f 25 git_filter_mode_t mode;
45c53eb6 26 uint32_t options;
570ba25c
RB
27};
28
85d54812
RB
29typedef struct {
30 git_filter *filter;
31 void *payload;
32} git_filter_entry;
33
34struct git_filter_list {
35 git_array_t(git_filter_entry) filters;
85d54812
RB
36 git_filter_source source;
37 char path[GIT_FLEX_ARRAY];
38};
39
40typedef struct {
5623e627 41 char *filter_name;
85d54812 42 git_filter *filter;
974774c7 43 int priority;
29e92d38 44 int initialized;
974774c7
RB
45 size_t nattrs, nmatches;
46 char *attrdata;
47 const char *attrs[GIT_FLEX_ARRAY];
85d54812
RB
48} git_filter_def;
49
974774c7
RB
50static int filter_def_priority_cmp(const void *a, const void *b)
51{
52 int pa = ((const git_filter_def *)a)->priority;
53 int pb = ((const git_filter_def *)b)->priority;
54 return (pa < pb) ? -1 : (pa > pb) ? 1 : 0;
55}
56
0646634e
RB
57struct filter_registry {
58 git_vector filters;
974774c7
RB
59};
60
0646634e
RB
61static struct filter_registry *git__filter_registry = NULL;
62
63static void filter_registry_shutdown(void)
64{
65 struct filter_registry *reg = NULL;
66 size_t pos;
67 git_filter_def *fdef;
68
69 if ((reg = git__swap(git__filter_registry, NULL)) == NULL)
70 return;
71
72 git_vector_foreach(&reg->filters, pos, fdef) {
9cfce273 73 if (fdef->filter && fdef->filter->shutdown) {
0646634e
RB
74 fdef->filter->shutdown(fdef->filter);
75 fdef->initialized = false;
76 }
77
5623e627 78 git__free(fdef->filter_name);
0646634e
RB
79 git__free(fdef->attrdata);
80 git__free(fdef);
81 }
82
83 git_vector_free(&reg->filters);
84 git__free(reg);
85}
86
87static int filter_registry_initialize(void)
88{
89 int error = 0;
90 struct filter_registry *reg;
91
92 if (git__filter_registry)
93 return 0;
94
95 reg = git__calloc(1, sizeof(struct filter_registry));
96 GITERR_CHECK_ALLOC(reg);
97
98 if ((error = git_vector_init(
99 &reg->filters, 2, filter_def_priority_cmp)) < 0)
100 goto cleanup;
101
102 reg = git__compare_and_swap(&git__filter_registry, NULL, reg);
103 if (reg != NULL)
104 goto cleanup;
105
106 git__on_shutdown(filter_registry_shutdown);
107
4b11f25a
RB
108 /* try to register both default filters */
109 {
110 git_filter *crlf = git_crlf_filter_new();
111 git_filter *ident = git_ident_filter_new();
112
113 if (crlf && git_filter_register(
114 GIT_FILTER_CRLF, crlf, GIT_FILTER_CRLF_PRIORITY) < 0)
115 crlf = NULL;
116 if (ident && git_filter_register(
117 GIT_FILTER_IDENT, ident, GIT_FILTER_IDENT_PRIORITY) < 0)
118 ident = NULL;
119
120 if (!crlf || !ident)
121 return -1;
122 }
123
124 return 0;
0646634e
RB
125
126cleanup:
127 git_vector_free(&reg->filters);
128 git__free(reg);
129 return error;
130}
131
974774c7
RB
132static int filter_def_scan_attrs(
133 git_buf *attrs, size_t *nattr, size_t *nmatch, const char *attr_str)
134{
135 const char *start, *scan = attr_str;
136 int has_eq;
137
138 *nattr = *nmatch = 0;
139
140 if (!scan)
141 return 0;
142
143 while (*scan) {
144 while (git__isspace(*scan)) scan++;
145
146 for (start = scan, has_eq = 0; *scan && !git__isspace(*scan); ++scan) {
147 if (*scan == '=')
148 has_eq = 1;
149 }
150
151 if (scan > start) {
152 (*nattr)++;
4b11f25a 153 if (has_eq || *start == '-' || *start == '+' || *start == '!')
974774c7
RB
154 (*nmatch)++;
155
156 if (has_eq)
157 git_buf_putc(attrs, '=');
158 git_buf_put(attrs, start, scan - start);
159 git_buf_putc(attrs, '\0');
160 }
161 }
162
163 return 0;
164}
165
166static void filter_def_set_attrs(git_filter_def *fdef)
167{
168 char *scan = fdef->attrdata;
169 size_t i;
170
171 for (i = 0; i < fdef->nattrs; ++i) {
172 const char *name, *value;
173
174 switch (*scan) {
175 case '=':
176 name = scan + 1;
177 for (scan++; *scan != '='; scan++) /* find '=' */;
178 *scan++ = '\0';
179 value = scan;
180 break;
181 case '-':
182 name = scan + 1; value = git_attr__false; break;
183 case '+':
184 name = scan + 1; value = git_attr__true; break;
185 case '!':
186 name = scan + 1; value = git_attr__unset; break;
187 default:
188 name = scan; value = NULL; break;
189 }
190
191 fdef->attrs[i] = name;
192 fdef->attrs[i + fdef->nattrs] = value;
193
194 scan += strlen(scan) + 1;
195 }
196}
197
0646634e
RB
198static int filter_def_name_key_check(const void *key, const void *fdef)
199{
200 const char *name =
201 fdef ? ((const git_filter_def *)fdef)->filter_name : NULL;
40cb40fa
RB
202 return name ? git__strcmp(key, name) : -1;
203}
204
205static int filter_def_filter_key_check(const void *key, const void *fdef)
206{
207 const void *filter = fdef ? ((const git_filter_def *)fdef)->filter : NULL;
208 return (key == filter) ? 0 : -1;
0646634e
RB
209}
210
211static int filter_registry_find(size_t *pos, const char *name)
212{
213 return git_vector_search2(
214 pos, &git__filter_registry->filters, filter_def_name_key_check, name);
215}
216
217static git_filter_def *filter_registry_lookup(size_t *pos, const char *name)
218{
219 git_filter_def *fdef = NULL;
220
221 if (!filter_registry_find(pos, name))
222 fdef = git_vector_get(&git__filter_registry->filters, *pos);
223
224 return fdef;
225}
226
974774c7
RB
227int git_filter_register(
228 const char *name, git_filter *filter, int priority)
229{
230 git_filter_def *fdef;
392702ee 231 size_t nattr = 0, nmatch = 0, alloc_len;
974774c7
RB
232 git_buf attrs = GIT_BUF_INIT;
233
5623e627
AGO
234 assert(name && filter);
235
0646634e
RB
236 if (filter_registry_initialize() < 0)
237 return -1;
238
239 if (!filter_registry_find(NULL, name)) {
974774c7
RB
240 giterr_set(
241 GITERR_FILTER, "Attempt to reregister existing filter '%s'", name);
eefc32d5 242 return GIT_EEXISTS;
974774c7
RB
243 }
244
245 if (filter_def_scan_attrs(&attrs, &nattr, &nmatch, filter->attributes) < 0)
246 return -1;
247
f1453c59
ET
248 GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, nattr, 2);
249 GITERR_CHECK_ALLOC_MULTIPLY(&alloc_len, alloc_len, sizeof(char *));
250 GITERR_CHECK_ALLOC_ADD(&alloc_len, alloc_len, sizeof(git_filter_def));
392702ee
ET
251
252 fdef = git__calloc(1, alloc_len);
974774c7
RB
253 GITERR_CHECK_ALLOC(fdef);
254
5623e627
AGO
255 fdef->filter_name = git__strdup(name);
256 GITERR_CHECK_ALLOC(fdef->filter_name);
257
974774c7
RB
258 fdef->filter = filter;
259 fdef->priority = priority;
260 fdef->nattrs = nattr;
261 fdef->nmatches = nmatch;
262 fdef->attrdata = git_buf_detach(&attrs);
263
264 filter_def_set_attrs(fdef);
265
0646634e 266 if (git_vector_insert(&git__filter_registry->filters, fdef) < 0) {
5623e627 267 git__free(fdef->filter_name);
974774c7
RB
268 git__free(fdef->attrdata);
269 git__free(fdef);
270 return -1;
271 }
272
0646634e 273 git_vector_sort(&git__filter_registry->filters);
29e92d38
RB
274 return 0;
275}
276
974774c7
RB
277int git_filter_unregister(const char *name)
278{
279 size_t pos;
280 git_filter_def *fdef;
281
5623e627
AGO
282 assert(name);
283
974774c7 284 /* cannot unregister default filters */
eefc32d5 285 if (!strcmp(GIT_FILTER_CRLF, name) || !strcmp(GIT_FILTER_IDENT, name)) {
974774c7
RB
286 giterr_set(GITERR_FILTER, "Cannot unregister filter '%s'", name);
287 return -1;
288 }
289
0646634e 290 if ((fdef = filter_registry_lookup(&pos, name)) == NULL) {
974774c7
RB
291 giterr_set(GITERR_FILTER, "Cannot find filter '%s' to unregister", name);
292 return GIT_ENOTFOUND;
293 }
294
0646634e 295 (void)git_vector_remove(&git__filter_registry->filters, pos);
974774c7 296
29e92d38 297 if (fdef->initialized && fdef->filter && fdef->filter->shutdown) {
974774c7 298 fdef->filter->shutdown(fdef->filter);
29e92d38
RB
299 fdef->initialized = false;
300 }
974774c7 301
5623e627 302 git__free(fdef->filter_name);
974774c7
RB
303 git__free(fdef->attrdata);
304 git__free(fdef);
305
306 return 0;
307}
308
0646634e
RB
309static int filter_initialize(git_filter_def *fdef)
310{
311 int error = 0;
312
313 if (!fdef->initialized &&
314 fdef->filter &&
315 fdef->filter->initialize &&
316 (error = fdef->filter->initialize(fdef->filter)) < 0)
317 {
318 /* auto-unregister if initialize fails */
319 git_filter_unregister(fdef->filter_name);
320 return error;
321 }
322
323 fdef->initialized = true;
324 return 0;
325}
326
974774c7
RB
327git_filter *git_filter_lookup(const char *name)
328{
329 size_t pos;
0646634e
RB
330 git_filter_def *fdef;
331
332 if (filter_registry_initialize() < 0)
333 return NULL;
29e92d38 334
0646634e 335 if ((fdef = filter_registry_lookup(&pos, name)) == NULL)
29e92d38
RB
336 return NULL;
337
338 if (!fdef->initialized && filter_initialize(fdef) < 0)
339 return NULL;
340
341 return fdef->filter;
974774c7
RB
342}
343
4b11f25a
RB
344void git_filter_free(git_filter *filter)
345{
346 git__free(filter);
347}
348
570ba25c
RB
349git_repository *git_filter_source_repo(const git_filter_source *src)
350{
351 return src->repo;
352}
353
354const char *git_filter_source_path(const git_filter_source *src)
355{
356 return src->path;
357}
358
359uint16_t git_filter_source_filemode(const git_filter_source *src)
360{
361 return src->filemode;
362}
363
364const git_oid *git_filter_source_id(const git_filter_source *src)
365{
366 return git_oid_iszero(&src->oid) ? NULL : &src->oid;
367}
368
2a7d224f
RB
369git_filter_mode_t git_filter_source_mode(const git_filter_source *src)
370{
371 return src->mode;
372}
373
45c53eb6 374uint32_t git_filter_source_options(const git_filter_source *src)
5269008c
RB
375{
376 return src->options;
377}
378
40cb40fa 379static int filter_list_new(
2a7d224f 380 git_filter_list **out, const git_filter_source *src)
27950fa3 381{
85d54812 382 git_filter_list *fl = NULL;
f1453c59 383 size_t pathlen = src->path ? strlen(src->path) : 0, alloclen;
85d54812 384
f1453c59
ET
385 GITERR_CHECK_ALLOC_ADD(&alloclen, sizeof(git_filter_list), pathlen);
386 GITERR_CHECK_ALLOC_ADD(&alloclen, alloclen, 1);
392702ee 387
f1453c59 388 fl = git__calloc(1, alloclen);
85d54812
RB
389 GITERR_CHECK_ALLOC(fl);
390
85d54812
RB
391 if (src->path)
392 memcpy(fl->path, src->path, pathlen);
393 fl->source.repo = src->repo;
394 fl->source.path = fl->path;
2a7d224f 395 fl->source.mode = src->mode;
5269008c 396 fl->source.options = src->options;
85d54812
RB
397
398 *out = fl;
399 return 0;
400}
401
974774c7 402static int filter_list_check_attributes(
9f779aac
ET
403 const char ***out,
404 git_repository *repo,
405 git_attr_session *attr_session,
406 git_filter_def *fdef,
407 const git_filter_source *src)
974774c7
RB
408{
409 int error;
410 size_t i;
411 const char **strs = git__calloc(fdef->nattrs, sizeof(const char *));
412 GITERR_CHECK_ALLOC(strs);
413
9f779aac
ET
414 error = git_attr_get_many_with_session(
415 strs, repo, attr_session, 0, src->path, fdef->nattrs, fdef->attrs);
974774c7
RB
416
417 /* if no values were found but no matches are needed, it's okay! */
418 if (error == GIT_ENOTFOUND && !fdef->nmatches) {
419 giterr_clear();
e399c7ee 420 git__free((void *)strs);
974774c7
RB
421 return 0;
422 }
423
424 for (i = 0; !error && i < fdef->nattrs; ++i) {
425 const char *want = fdef->attrs[fdef->nattrs + i];
426 git_attr_t want_type, found_type;
427
428 if (!want)
429 continue;
430
431 want_type = git_attr_value(want);
432 found_type = git_attr_value(strs[i]);
433
434 if (want_type != found_type ||
435 (want_type == GIT_ATTR_VALUE_T && strcmp(want, strs[i])))
436 error = GIT_ENOTFOUND;
437 }
438
439 if (error)
e399c7ee 440 git__free((void *)strs);
974774c7
RB
441 else
442 *out = strs;
443
444 return error;
445}
446
40cb40fa 447int git_filter_list_new(
5269008c
RB
448 git_filter_list **out,
449 git_repository *repo,
450 git_filter_mode_t mode,
45c53eb6 451 uint32_t options)
40cb40fa
RB
452{
453 git_filter_source src = { 0 };
454 src.repo = repo;
455 src.path = NULL;
456 src.mode = mode;
5269008c 457 src.options = options;
40cb40fa
RB
458 return filter_list_new(out, &src);
459}
460
9f779aac 461int git_filter_list__load_with_attr_session(
85d54812
RB
462 git_filter_list **filters,
463 git_repository *repo,
9f779aac 464 git_attr_session *attr_session,
4b11f25a 465 git_blob *blob, /* can be NULL */
85d54812 466 const char *path,
5269008c 467 git_filter_mode_t mode,
45c53eb6 468 uint32_t options)
85d54812
RB
469{
470 int error = 0;
471 git_filter_list *fl = NULL;
472 git_filter_source src = { 0 };
473 git_filter_entry *fe;
974774c7
RB
474 size_t idx;
475 git_filter_def *fdef;
85d54812 476
0646634e 477 if (filter_registry_initialize() < 0)
85d54812
RB
478 return -1;
479
480 src.repo = repo;
481 src.path = path;
2a7d224f 482 src.mode = mode;
5269008c 483 src.options = options;
4b11f25a
RB
484 if (blob)
485 git_oid_cpy(&src.oid, git_blob_id(blob));
85d54812 486
0646634e 487 git_vector_foreach(&git__filter_registry->filters, idx, fdef) {
974774c7 488 const char **values = NULL;
85d54812 489 void *payload = NULL;
85d54812
RB
490
491 if (!fdef || !fdef->filter)
492 continue;
27950fa3 493
974774c7 494 if (fdef->nattrs > 0) {
9f779aac
ET
495 error = filter_list_check_attributes(
496 &values, repo, attr_session, fdef, &src);
497
974774c7
RB
498 if (error == GIT_ENOTFOUND) {
499 error = 0;
500 continue;
501 } else if (error < 0)
502 break;
503 }
504
29e92d38
RB
505 if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
506 break;
507
85d54812 508 if (fdef->filter->check)
974774c7 509 error = fdef->filter->check(
2a7d224f 510 fdef->filter, &payload, &src, values);
974774c7 511
e399c7ee 512 git__free((void *)values);
85d54812 513
eefc32d5 514 if (error == GIT_PASSTHROUGH)
85d54812
RB
515 error = 0;
516 else if (error < 0)
517 break;
518 else {
40cb40fa 519 if (!fl && (error = filter_list_new(&fl, &src)) < 0)
85d54812
RB
520 return error;
521
522 fe = git_array_alloc(fl->filters);
523 GITERR_CHECK_ALLOC(fe);
524 fe->filter = fdef->filter;
525 fe->payload = payload;
526 }
527 }
528
529 if (error && fl != NULL) {
530 git_array_clear(fl->filters);
531 git__free(fl);
532 fl = NULL;
533 }
534
535 *filters = fl;
536 return error;
537}
538
9f779aac
ET
539int git_filter_list_load(
540 git_filter_list **filters,
541 git_repository *repo,
542 git_blob *blob, /* can be NULL */
543 const char *path,
544 git_filter_mode_t mode,
545 uint32_t options)
546{
547 return git_filter_list__load_with_attr_session(
548 filters, repo, NULL, blob, path, mode, options);
549}
550
85d54812
RB
551void git_filter_list_free(git_filter_list *fl)
552{
553 uint32_t i;
554
555 if (!fl)
556 return;
557
558 for (i = 0; i < git_array_size(fl->filters); ++i) {
559 git_filter_entry *fe = git_array_get(fl->filters, i);
560 if (fe->filter->cleanup)
561 fe->filter->cleanup(fe->filter, fe->payload);
27950fa3
VM
562 }
563
85d54812
RB
564 git_array_clear(fl->filters);
565 git__free(fl);
27950fa3
VM
566}
567
40cb40fa
RB
568int git_filter_list_push(
569 git_filter_list *fl, git_filter *filter, void *payload)
570{
571 int error = 0;
572 size_t pos;
573 git_filter_def *fdef;
574 git_filter_entry *fe;
575
576 assert(fl && filter);
577
578 if (git_vector_search2(
579 &pos, &git__filter_registry->filters,
580 filter_def_filter_key_check, filter) < 0) {
581 giterr_set(GITERR_FILTER, "Cannot use an unregistered filter");
582 return -1;
583 }
584
585 fdef = git_vector_get(&git__filter_registry->filters, pos);
586
587 if (!fdef->initialized && (error = filter_initialize(fdef)) < 0)
588 return error;
589
590 fe = git_array_alloc(fl->filters);
591 GITERR_CHECK_ALLOC(fe);
592 fe->filter = filter;
593 fe->payload = payload;
594
595 return 0;
596}
597
b47349b8
RB
598size_t git_filter_list_length(const git_filter_list *fl)
599{
600 return fl ? git_array_size(fl->filters) : 0;
601}
602
2a7d224f 603static int filter_list_out_buffer_from_raw(
a9f51e43 604 git_buf *out, const void *ptr, size_t size)
2a7d224f 605{
a9f51e43
RB
606 if (git_buf_is_allocated(out))
607 git_buf_free(out);
608
609 if (!size) {
610 git_buf_init(out, 0);
611 } else {
612 out->ptr = (char *)ptr;
613 out->asize = 0;
614 out->size = size;
615 }
2a7d224f 616
2a7d224f
RB
617 return 0;
618}
619
620int git_filter_list_apply_to_data(
a9f51e43 621 git_buf *tgt, git_filter_list *fl, git_buf *src)
44b1ff4c 622{
85d54812
RB
623 int error = 0;
624 uint32_t i;
a9f51e43 625 git_buf *dbuffer[2], local = GIT_BUF_INIT;
2a7d224f 626 unsigned int si = 0;
44b1ff4c 627
1e4976cb
RB
628 git_buf_sanitize(tgt);
629 git_buf_sanitize(src);
630
2a7d224f
RB
631 if (!fl)
632 return filter_list_out_buffer_from_raw(tgt, src->ptr, src->size);
44b1ff4c 633
2a7d224f
RB
634 dbuffer[0] = src;
635 dbuffer[1] = tgt;
44b1ff4c 636
2a7d224f 637 /* if `src` buffer is reallocable, then use it, otherwise copy it */
a9f51e43
RB
638 if (!git_buf_is_allocated(src)) {
639 if (git_buf_set(&local, src->ptr, src->size) < 0)
2a7d224f
RB
640 return -1;
641 dbuffer[0] = &local;
642 }
44b1ff4c 643
85d54812 644 for (i = 0; i < git_array_size(fl->filters); ++i) {
2a7d224f 645 unsigned int di = 1 - si;
37f9e409 646 uint32_t fidx = (fl->source.mode == GIT_FILTER_TO_WORKTREE) ?
2a7d224f
RB
647 i : git_array_size(fl->filters) - 1 - i;
648 git_filter_entry *fe = git_array_get(fl->filters, fidx);
44b1ff4c 649
2a7d224f 650 dbuffer[di]->size = 0;
974774c7 651
ce49c7a8 652 /* Apply the filter from dbuffer[src] to the other buffer;
44b1ff4c
VM
653 * if the filtering is canceled by the user mid-filter,
654 * we skip to the next filter without changing the source
655 * of the double buffering (so that the text goes through
656 * cleanly).
657 */
85d54812 658
2a7d224f
RB
659 error = fe->filter->apply(
660 fe->filter, &fe->payload, dbuffer[di], dbuffer[si], &fl->source);
85d54812 661
eefc32d5
RB
662 if (error == GIT_PASSTHROUGH) {
663 /* PASSTHROUGH means filter decided not to process the buffer */
2a7d224f 664 error = 0;
eefc32d5 665 } else if (!error) {
1e4976cb 666 git_buf_sanitize(dbuffer[di]); /* force NUL termination */
2a7d224f 667 si = di; /* swap buffers */
eefc32d5 668 } else {
2a7d224f 669 tgt->size = 0;
424222f4 670 goto cleanup;
85d54812 671 }
44b1ff4c
VM
672 }
673
674 /* Ensure that the output ends up in dbuffer[1] (i.e. the dest) */
a9f51e43
RB
675 if (si != 1)
676 git_buf_swap(dbuffer[0], dbuffer[1]);
2a7d224f 677
424222f4 678cleanup:
a9f51e43 679 git_buf_free(&local); /* don't leak if we allocated locally */
44b1ff4c 680
424222f4 681 return error;
44b1ff4c 682}
2a7d224f
RB
683
684int git_filter_list_apply_to_file(
a9f51e43 685 git_buf *out,
2a7d224f
RB
686 git_filter_list *filters,
687 git_repository *repo,
688 const char *path)
689{
690 int error;
691 const char *base = repo ? git_repository_workdir(repo) : NULL;
692 git_buf abspath = GIT_BUF_INIT, raw = GIT_BUF_INIT;
693
694 if (!(error = git_path_join_unrooted(&abspath, path, base, NULL)) &&
695 !(error = git_futils_readbuffer(&raw, abspath.ptr)))
696 {
a9f51e43 697 error = git_filter_list_apply_to_data(out, filters, &raw);
2a7d224f 698
a9f51e43 699 git_buf_free(&raw);
2a7d224f
RB
700 }
701
702 git_buf_free(&abspath);
703 return error;
704}
705
706int git_filter_list_apply_to_blob(
a9f51e43 707 git_buf *out,
2a7d224f
RB
708 git_filter_list *filters,
709 git_blob *blob)
710{
71379313
RB
711 git_buf in = GIT_BUF_INIT;
712 git_off_t rawsize = git_blob_rawsize(blob);
713
714 if (!git__is_sizet(rawsize)) {
715 giterr_set(GITERR_OS, "Blob is too large to filter");
716 return -1;
717 }
718
719 in.ptr = (char *)git_blob_rawcontent(blob);
720 in.asize = 0;
721 in.size = (size_t)rawsize;
2a7d224f 722
4b11f25a
RB
723 if (filters)
724 git_oid_cpy(&filters->source.oid, git_blob_id(blob));
725
2a7d224f
RB
726 return git_filter_list_apply_to_data(out, filters, &in);
727}