diff --git a/config.c b/config.c index 85f2b3c8975fc6..86a2aeafc99773 100644 --- a/config.c +++ b/config.c @@ -1808,6 +1808,11 @@ static int git_default_gvfs_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "gvfs.trustidxfiles")) { + gvfs_trust_idx_files = git_config_bool(var, value); + return 0; + } + return 0; } diff --git a/environment.c b/environment.c index c0b9155cd61228..7dd9ac516efab8 100644 --- a/environment.c +++ b/environment.c @@ -101,6 +101,7 @@ int protect_ntfs = PROTECT_NTFS_DEFAULT; int core_use_gvfs_helper; char *gvfs_cache_server_url; struct strbuf gvfs_shared_cache_pathname = STRBUF_INIT; +int gvfs_trust_idx_files = -1; /* default to unset */ /* * The character that begins a commented line in user-editable file diff --git a/environment.h b/environment.h index f781830d748896..a27455076cb7e5 100644 --- a/environment.h +++ b/environment.h @@ -167,6 +167,7 @@ extern int protect_ntfs; extern int core_use_gvfs_helper; extern char *gvfs_cache_server_url; extern struct strbuf gvfs_shared_cache_pathname; +extern int gvfs_trust_idx_files; extern int core_apply_sparse_checkout; extern int core_sparse_checkout_cone; diff --git a/gvfs-helper.c b/gvfs-helper.c index 60c54f61af106a..3f22df0f88ccb5 100644 --- a/gvfs-helper.c +++ b/gvfs-helper.c @@ -2199,31 +2199,56 @@ static void extract_packfile_from_multipack( oid_to_hex_r(hex_checksum, &packfile_checksum); - /* - * Always compute the .idx file from the .pack file. - */ - strbuf_addbuf(&temp_path_idx, &temp_path_pack); - strbuf_strip_suffix(&temp_path_idx, ".pack"); - strbuf_addstr(&temp_path_idx, ".idx"); + if (b_no_idx_in_multipack || gvfs_trust_idx_files <= 0) { + /* + * If the multipack does not contain an index, or we are + * not trusting the received index, we will compute it + * locally. + */ + strbuf_addbuf(&temp_path_idx, &temp_path_pack); + strbuf_strip_suffix(&temp_path_idx, ".pack"); + strbuf_addstr(&temp_path_idx, ".idx"); - my_run_index_pack(params, status, - &temp_path_pack, &temp_path_idx, - NULL); - if (status->ec != GH__ERROR_CODE__OK) - goto done; + my_run_index_pack(params, status, + &temp_path_pack, &temp_path_idx, + NULL); + if (status->ec != GH__ERROR_CODE__OK) + goto done; - if (!b_no_idx_in_multipack) { + if (!b_no_idx_in_multipack) { + /* + * Server sent the .idx immediately after the .pack in the + * data stream. Skip over it. + */ + if (lseek(fd_multipack, ph.idx_len, SEEK_CUR) < 0) { + strbuf_addf(&status->error_message, + "could not skip index[%d] in multipack", + k); + status->ec = GH__ERROR_CODE__COULD_NOT_INSTALL_PREFETCH; + goto done; + } + } + } else { /* - * Server sent the .idx immediately after the .pack in the - * data stream. Skip over it. + * If the multipack contains an index and we trust it, + * then we will use it. */ - if (lseek(fd_multipack, ph.idx_len, SEEK_CUR) < 0) { + my_create_tempfile(status, 0, "pack", &tempfile_pack, NULL, NULL); + if (!tempfile_pack) + goto done; + + result = my_copy_fd_len(fd_multipack, + get_tempfile_fd(tempfile_pack), + ph.idx_len); + + if (result < 0) { strbuf_addf(&status->error_message, - "could not skip index[%d] in multipack", - k); - status->ec = GH__ERROR_CODE__COULD_NOT_INSTALL_PREFETCH; + "could not extract packfile index [%d] from multipack", + k); goto done; } + strbuf_addstr(&temp_path_idx, get_tempfile_path(tempfile_pack)); + close_tempfile_gently(tempfile_pack); } strbuf_addf(&buf_timestamp, "%u", (unsigned int)ph.timestamp); diff --git a/scalar.c b/scalar.c index 1e97538979155a..75a4402e7005dc 100644 --- a/scalar.c +++ b/scalar.c @@ -7,6 +7,7 @@ #include "git-compat-util.h" #include "abspath.h" #include "gettext.h" +#include "environment.h" #include "hex.h" #include "parse-options.h" #include "config.h" @@ -748,6 +749,7 @@ static int cmd_clone(int argc, const char **argv) const char *cache_server_url = NULL, *local_cache_root = NULL; char *default_cache_server_url = NULL, *local_cache_root_abs = NULL; int gvfs_protocol = -1; + int trust_idx = -1; struct option clone_options[] = { OPT_STRING('b', "branch", &branch, N_(""), @@ -763,6 +765,8 @@ static int cmd_clone(int argc, const char **argv) N_("specify if tags should be fetched during clone")), OPT_BOOL(0, "gvfs-protocol", &gvfs_protocol, N_("force enable (or disable) the GVFS Protocol")), + OPT_BOOL(0, "trust-idx", &trust_idx, + N_("force enable (or disable) trusting idx files received via GVFS Protocol")), OPT_STRING(0, "cache-server-url", &cache_server_url, N_(""), N_("the url or friendly name of the cache server")), @@ -908,6 +912,28 @@ static int cmd_clone(int argc, const char **argv) die(_("failed to contact server via GVFS Protocol")); if (gvfs_protocol) { + if (trust_idx == 0) { + /* User explicitly set not to trust idx for this enlistment*/ + if (set_config("gvfs.trustidxfiles=false")) { + res = error(_("could not configure not trusting idx files")); + goto cleanup; + } + } else if (trust_idx > 0 /* User specified --trust-idx */ + || (gvfs_trust_idx_files < 0 /* global config not set */ + && (strstr(url, "dev.azure.com/") + || strstr(url, "visualstudio.com")) /* Well-known url */ + ) + ) { + /* + * If global config for gvfs.trustidxfiles is not set, then we + * default to trusting idx files for well-known urls + */ + if (set_config("gvfs.trustidxfiles=true")) { + res = error(_("could not configure trusting idx files")); + goto cleanup; + }; + } + if ((res = init_shared_object_cache(url, local_cache_root))) goto cleanup; if (!cache_server_url)