Skip to content

Commit 750ef42

Browse files
spearcegitster
authored andcommitted
http-fetch: Use temporary files for pack-*.idx until verified
Verify that a downloaded pack-*.idx file is consistent and valid as an index file before we rename it into its final destination. This prevents a corrupt index file from later being treated as a usable file, confusing readers. Check that we do not have the pack index file before invoking fetch_pack_index(); that way, we can do without the has_pack_index() check in fetch_pack_index(). Signed-off-by: Shawn O. Pearce <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fe72d42 commit 750ef42

File tree

2 files changed

+54
-17
lines changed

2 files changed

+54
-17
lines changed

http.c

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -897,45 +897,67 @@ int http_fetch_ref(const char *base, struct ref *ref)
897897
}
898898

899899
/* Helpers for fetching packs */
900-
static int fetch_pack_index(unsigned char *sha1, const char *base_url)
900+
static char *fetch_pack_index(unsigned char *sha1, const char *base_url)
901901
{
902-
int ret = 0;
903-
char *filename;
904-
char *url = NULL;
902+
char *url, *tmp;
905903
struct strbuf buf = STRBUF_INIT;
906904

907-
if (has_pack_index(sha1)) {
908-
ret = 0;
909-
goto cleanup;
910-
}
911-
912905
if (http_is_verbose)
913906
fprintf(stderr, "Getting index for pack %s\n", sha1_to_hex(sha1));
914907

915908
end_url_with_slash(&buf, base_url);
916909
strbuf_addf(&buf, "objects/pack/pack-%s.idx", sha1_to_hex(sha1));
917910
url = strbuf_detach(&buf, NULL);
918911

919-
filename = sha1_pack_index_name(sha1);
920-
if (http_get_file(url, filename, 0) != HTTP_OK)
921-
ret = error("Unable to get pack index %s\n", url);
912+
strbuf_addf(&buf, "%s.temp", sha1_pack_index_name(sha1));
913+
tmp = strbuf_detach(&buf, NULL);
914+
915+
if (http_get_file(url, tmp, 0) != HTTP_OK) {
916+
error("Unable to get pack index %s\n", url);
917+
free(tmp);
918+
tmp = NULL;
919+
}
922920

923-
cleanup:
924921
free(url);
925-
return ret;
922+
return tmp;
926923
}
927924

928925
static int fetch_and_setup_pack_index(struct packed_git **packs_head,
929926
unsigned char *sha1, const char *base_url)
930927
{
931928
struct packed_git *new_pack;
929+
char *tmp_idx = NULL;
930+
int ret;
931+
932+
if (has_pack_index(sha1)) {
933+
new_pack = parse_pack_index(sha1, NULL);
934+
if (!new_pack)
935+
return -1; /* parse_pack_index() already issued error message */
936+
goto add_pack;
937+
}
932938

933-
if (fetch_pack_index(sha1, base_url))
939+
tmp_idx = fetch_pack_index(sha1, base_url);
940+
if (!tmp_idx)
934941
return -1;
935942

936-
new_pack = parse_pack_index(sha1, sha1_pack_index_name(sha1));
937-
if (!new_pack)
943+
new_pack = parse_pack_index(sha1, tmp_idx);
944+
if (!new_pack) {
945+
unlink(tmp_idx);
946+
free(tmp_idx);
947+
938948
return -1; /* parse_pack_index() already issued error message */
949+
}
950+
951+
ret = verify_pack_index(new_pack);
952+
if (!ret) {
953+
close_pack_index(new_pack);
954+
ret = move_temp_to_file(tmp_idx, sha1_pack_index_name(sha1));
955+
}
956+
free(tmp_idx);
957+
if (ret)
958+
return -1;
959+
960+
add_pack:
939961
new_pack->next = *packs_head;
940962
*packs_head = new_pack;
941963
return 0;

t/t5550-http-fetch.sh

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,21 @@ test_expect_success 'fetch notices corrupt pack' '
7777
)
7878
'
7979

80+
test_expect_success 'fetch notices corrupt idx' '
81+
cp -R "$HTTPD_DOCUMENT_ROOT_PATH"/repo_pack.git "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
82+
(cd "$HTTPD_DOCUMENT_ROOT_PATH"/repo_bad2.git &&
83+
p=`ls objects/pack/pack-*.idx` &&
84+
chmod u+w $p &&
85+
printf %0256d 0 | dd of=$p bs=256 count=1 seek=1 conv=notrunc
86+
) &&
87+
mkdir repo_bad2.git &&
88+
(cd repo_bad2.git &&
89+
git --bare init &&
90+
test_must_fail git --bare fetch $HTTPD_URL/dumb/repo_bad2.git &&
91+
test 0 = `ls objects/pack | wc -l`
92+
)
93+
'
94+
8095
test_expect_success 'did not use upload-pack service' '
8196
grep '/git-upload-pack' <"$HTTPD_ROOT_PATH"/access.log >act
8297
: >exp

0 commit comments

Comments
 (0)