static int bitflip_filter_apply( git_filter *self, void **payload, git_buf *to, const git_buf *from, const git_filter_source *source) { const unsigned char *src = (const unsigned char *)from->ptr; unsigned char *dst; size_t i; GIT_UNUSED(self); GIT_UNUSED(payload); /* verify that attribute path match worked as expected */ cl_assert_equal_i( 0, git__strncmp("hero", git_filter_source_path(source), 4)); if (!from->size) return 0; cl_git_pass(git_buf_grow(to, from->size)); dst = (unsigned char *)to->ptr; for (i = 0; i < from->size; i++) dst[i] = VERY_SECURE_ENCRYPTION(src[i]); to->size = from->size; return 0; }
static int reverse_filter_apply( git_filter *self, void **payload, git_buf *to, const git_buf *from, const git_filter_source *source) { const unsigned char *src = (const unsigned char *)from->ptr; const unsigned char *end = src + from->size; unsigned char *dst; GIT_UNUSED(self); GIT_UNUSED(payload); GIT_UNUSED(source); /* verify that attribute path match worked as expected */ cl_assert_equal_i( 0, git__strncmp("hero", git_filter_source_path(source), 4)); if (!from->size) return 0; cl_git_pass(git_buf_grow(to, from->size)); dst = (unsigned char *)to->ptr + from->size - 1; while (src < end) *dst-- = *src++; to->size = from->size; return 0; }
static int has_cr_in_index(const git_filter_source *src) { git_repository *repo = git_filter_source_repo(src); const char *path = git_filter_source_path(src); git_index *index; const git_index_entry *entry; git_blob *blob; const void *blobcontent; git_off_t blobsize; bool found_cr; if (!path) return false; if (git_repository_index__weakptr(&index, repo) < 0) { giterr_clear(); return false; } if (!(entry = git_index_get_bypath(index, path, 0)) && !(entry = git_index_get_bypath(index, path, 1))) return false; if (!S_ISREG(entry->mode)) /* don't crlf filter non-blobs */ return true; if (git_blob_lookup(&blob, repo, &entry->id) < 0) return false; blobcontent = git_blob_rawcontent(blob); blobsize = git_blob_rawsize(blob); if (!git__is_sizet(blobsize)) blobsize = (size_t)-1; found_cr = (blobcontent != NULL && blobsize > 0 && memchr(blobcontent, '\r', (size_t)blobsize) != NULL); git_blob_free(blob); return found_cr; }
static int filter_apply( git_filter *self, void **payload, /* may be read and/or set */ git_buf *to, const git_buf *from, const git_filter_source *src) { struct filter_filter *ffs = (struct filter_filter *)self; git_config *config; git_buf configKey = GIT_BUF_INIT; int isRequired = FALSE; int error; const char *cmd = NULL; git_buf cmdBuf = GIT_BUF_INIT; wchar_t *wide_cmd; COMMAND_HANDLE commandHandle = COMMAND_HANDLE_INIT; git_buf errBuf = GIT_BUF_INIT; DWORD exitCode; if (!*payload) return GIT_PASSTHROUGH; if (git_repository_config__weakptr(&config, git_filter_source_repo(src))) return -1; git_buf_join3(&configKey, '.', "filter", *payload, "required"); if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_bool(&isRequired, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; git_buf_join(&configKey, '.', "filter", *payload); if (git_filter_source_mode(src) == GIT_FILTER_SMUDGE) { git_buf_puts(&configKey, ".smudge"); } else { git_buf_puts(&configKey, ".clean"); } if (git_buf_oom(&configKey)) { giterr_set_oom(); return -1; } error = git_config_get_string(&cmd, config, configKey.ptr); git_buf_free(&configKey); if (error && error != GIT_ENOTFOUND) return -1; if (error == GIT_ENOTFOUND) { if (isRequired) return -1; return GIT_PASSTHROUGH; } git_buf_puts(&cmdBuf, cmd); if (git_buf_oom(&cmdBuf)) { giterr_set_oom(); return -1; } if (expandPerCentF(&cmdBuf, git_filter_source_path(src))) return -1; if (ffs->shexepath) { // build params for sh.exe git_buf shParams = GIT_BUF_INIT; git_buf_puts(&shParams, " -c \""); git_buf_text_puts_escaped(&shParams, cmdBuf.ptr, "\"\\", "\\"); git_buf_puts(&shParams, "\""); if (git_buf_oom(&shParams)) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_swap(&shParams, &cmdBuf); git_buf_free(&shParams); } if (git__utf8_to_16_alloc(&wide_cmd, cmdBuf.ptr) < 0) { git_buf_free(&cmdBuf); giterr_set_oom(); return -1; } git_buf_free(&cmdBuf); if (ffs->shexepath) { // build cmd, i.e. shexepath + params size_t len = wcslen(ffs->shexepath) + wcslen(wide_cmd) + 1; wchar_t *tmp = git__calloc(len, sizeof(wchar_t)); if (!tmp) { git__free(wide_cmd); giterr_set_oom(); return -1; } wcscat_s(tmp, len, ffs->shexepath); wcscat_s(tmp, len, wide_cmd); git__free(wide_cmd); wide_cmd = tmp; } commandHandle.errBuf = &errBuf; if (command_start(wide_cmd, &commandHandle, ffs->pEnv)) { git__free(wide_cmd); if (isRequired) return -1; return GIT_PASSTHROUGH; } git__free(wide_cmd); if (commmand_start_stdout_reading_thread(&commandHandle, to)) { command_close(&commandHandle); return -1; } if (command_write_gitbuf(&commandHandle, from)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } command_close_stdin(&commandHandle); if (command_wait_stdout_reading_thread(&commandHandle)) { DWORD exitCode = command_close(&commandHandle); if (exitCode) setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); if (isRequired) return -1; return GIT_PASSTHROUGH; } exitCode = command_close(&commandHandle); if (exitCode) { if (isRequired) { setProcessError(exitCode, &errBuf); git_buf_free(&errBuf); return -1; } git_buf_free(&errBuf); return GIT_PASSTHROUGH; } git_buf_free(&errBuf); return 0; }
static int crlf_apply_to_odb( struct crlf_attrs *ca, git_buf *to, const git_buf *from, const git_filter_source *src) { /* Empty file? Nothing to do */ if (!git_buf_len(from)) return 0; /* Heuristics to see if we can skip the conversion. * Straight from Core Git. */ if (ca->crlf_action == GIT_CRLF_AUTO || ca->crlf_action == GIT_CRLF_GUESS) { git_buf_text_stats stats; /* Check heuristics for binary vs text - returns true if binary */ if (git_buf_text_gather_stats(&stats, from, false)) return GIT_PASSTHROUGH; /* If there are no CR characters to filter out, then just pass */ if (!stats.cr) return GIT_PASSTHROUGH; /* If safecrlf is enabled, sanity-check the result. */ if (stats.cr != stats.crlf || stats.lf != stats.crlf) { switch (ca->safe_crlf) { case GIT_SAFE_CRLF_FAIL: giterr_set( GITERR_FILTER, "LF would be replaced by CRLF in '%s'", git_filter_source_path(src)); return -1; case GIT_SAFE_CRLF_WARN: /* TODO: issue warning when warning API is available */; break; default: break; } } /* * We're currently not going to even try to convert stuff * that has bare CR characters. Does anybody do that crazy * stuff? */ if (stats.cr != stats.crlf) return GIT_PASSTHROUGH; if (ca->crlf_action == GIT_CRLF_GUESS) { /* * If the file in the index has any CR in it, do not convert. * This is the new safer autocrlf handling. */ if (has_cr_in_index(src)) return GIT_PASSTHROUGH; } if (!stats.cr) return GIT_PASSTHROUGH; } /* Actually drop the carriage returns */ return git_buf_text_crlf_to_lf(to, from); }