X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=54648282592d85cea0b1d42e02f358c240991ce2;hb=73136b2e8a8ee024320c5ac6a0f14f912432bf03;hp=1fd5b797a587dfd52a6662fc48c992a5e298f7f8;hpb=597888adc6006cbca02175b6f070f8ef46b014e6;p=git.git diff --git a/sha1_file.c b/sha1_file.c index 1fd5b797..54648282 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -9,6 +9,10 @@ #include "cache.h" #include "delta.h" #include "pack.h" +#include "blob.h" +#include "commit.h" +#include "tag.h" +#include "tree.h" #ifndef O_NOATIME #if defined(__linux__) && (defined(__i386__) || defined(__PPC__)) @@ -104,9 +108,10 @@ int safe_create_leading_directories(char *path) char * sha1_to_hex(const unsigned char *sha1) { - static char buffer[50]; + static int bufno; + static char hexbuffer[4][50]; static const char hex[] = "0123456789abcdef"; - char *buf = buffer; + char *buffer = hexbuffer[3 & ++bufno], *buf = buffer; int i; for (i = 0; i < 20; i++) { @@ -564,7 +569,7 @@ static void prepare_packed_git_one(char *objdir, int local) dir = opendir(path); if (!dir) { if (errno != ENOENT) - error("unable to open object pack directory: %s: %s\n", + error("unable to open object pack directory: %s: %s", path, strerror(errno)); return; } @@ -804,10 +809,12 @@ static int packed_delta_info(unsigned char *base_sha1, * the result size. */ data = delta_head; - get_delta_hdr_size(&data); /* ignore base size */ + + /* ignore base size */ + get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); /* Read the result size */ - result_size = get_delta_hdr_size(&data); + result_size = get_delta_hdr_size(&data, delta_head+sizeof(delta_head)); *sizep = result_size; } return 0; @@ -868,17 +875,19 @@ void packed_object_info_detail(struct pack_entry *e, unsigned char *base_sha1) { struct packed_git *p = e->p; - unsigned long offset, left; + unsigned long offset; unsigned char *pack; enum object_type kind; offset = unpack_object_header(p, e->offset, &kind, size); pack = p->pack_base + offset; - left = p->pack_size - offset; if (kind != OBJ_DELTA) *delta_chain_length = 0; else { unsigned int chain_length = 0; + if (p->pack_size <= offset + 20) + die("pack file %s records an incomplete delta base", + p->pack_name); memcpy(base_sha1, pack, 20); do { struct pack_entry base_ent; @@ -894,16 +903,16 @@ void packed_object_info_detail(struct pack_entry *e, } switch (kind) { case OBJ_COMMIT: - strcpy(type, "commit"); + strcpy(type, commit_type); break; case OBJ_TREE: - strcpy(type, "tree"); + strcpy(type, tree_type); break; case OBJ_BLOB: - strcpy(type, "blob"); + strcpy(type, blob_type); break; case OBJ_TAG: - strcpy(type, "tag"); + strcpy(type, tag_type); break; default: die("corrupted pack file %s containing object of kind %d", @@ -934,16 +943,16 @@ static int packed_object_info(struct pack_entry *entry, unuse_packed_git(p); return retval; case OBJ_COMMIT: - strcpy(type, "commit"); + strcpy(type, commit_type); break; case OBJ_TREE: - strcpy(type, "tree"); + strcpy(type, tree_type); break; case OBJ_BLOB: - strcpy(type, "blob"); + strcpy(type, blob_type); break; case OBJ_TAG: - strcpy(type, "tag"); + strcpy(type, tag_type); break; default: die("corrupted pack file %s containing object of kind %d", @@ -973,6 +982,16 @@ static void *unpack_delta_entry(unsigned char *base_sha1, if (left < 20) die("truncated pack file"); + + /* The base entry _must_ be in the same pack */ + if (!find_pack_entry_one(base_sha1, &base_ent, p)) + die("failed to find delta-pack base object %s", + sha1_to_hex(base_sha1)); + base = unpack_entry_gently(&base_ent, type, &base_size); + if (!base) + die("failed to read delta-pack base object %s", + sha1_to_hex(base_sha1)); + data = base_sha1 + 20; data_size = left - 20; delta_data = xmalloc(delta_size); @@ -990,14 +1009,6 @@ static void *unpack_delta_entry(unsigned char *base_sha1, if ((st != Z_STREAM_END) || stream.total_out != delta_size) die("delta data unpack failed"); - /* The base entry _must_ be in the same pack */ - if (!find_pack_entry_one(base_sha1, &base_ent, p)) - die("failed to find delta-pack base object %s", - sha1_to_hex(base_sha1)); - base = unpack_entry_gently(&base_ent, type, &base_size); - if (!base) - die("failed to read delta-pack base object %s", - sha1_to_hex(base_sha1)); result = patch_delta(base, base_size, delta_data, delta_size, &result_size); @@ -1069,16 +1080,16 @@ void *unpack_entry_gently(struct pack_entry *entry, retval = unpack_delta_entry(pack, size, left, type, sizep, p); return retval; case OBJ_COMMIT: - strcpy(type, "commit"); + strcpy(type, commit_type); break; case OBJ_TREE: - strcpy(type, "tree"); + strcpy(type, tree_type); break; case OBJ_BLOB: - strcpy(type, "blob"); + strcpy(type, blob_type); break; case OBJ_TAG: - strcpy(type, "tag"); + strcpy(type, tag_type); break; default: return NULL; @@ -1239,9 +1250,9 @@ void *read_object_with_reference(const unsigned char *sha1, return buffer; } /* Handle references */ - else if (!strcmp(type, "commit")) + else if (!strcmp(type, commit_type)) ref_type = "tree "; - else if (!strcmp(type, "tag")) + else if (!strcmp(type, tag_type)) ref_type = "object "; else { free(buffer); @@ -1513,7 +1524,8 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer, local = mkstemp(tmpfile); if (local < 0) - return error("Couldn't open %s for %s\n", tmpfile, sha1_to_hex(sha1)); + return error("Couldn't open %s for %s", + tmpfile, sha1_to_hex(sha1)); memset(&stream, 0, sizeof(stream)); @@ -1561,7 +1573,7 @@ int write_sha1_from_fd(const unsigned char *sha1, int fd, char *buffer, } if (memcmp(sha1, real_sha1, 20)) { unlink(tmpfile); - return error("File %s has bad hash\n", sha1_to_hex(sha1)); + return error("File %s has bad hash", sha1_to_hex(sha1)); } return move_temp_to_file(tmpfile, sha1_file_name(sha1)); @@ -1622,7 +1634,7 @@ int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object) return -1; } if (!type) - type = "blob"; + type = blob_type; if (write_object) ret = write_sha1_file(buf, off, type, sha1); else { @@ -1649,7 +1661,7 @@ int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, con return -1; if (!type) - type = "blob"; + type = blob_type; if (write_object) ret = write_sha1_file(buf, size, type, sha1); else { @@ -1687,9 +1699,9 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write if (!write_object) { unsigned char hdr[50]; int hdrlen; - write_sha1_file_prepare(target, st->st_size, "blob", + write_sha1_file_prepare(target, st->st_size, blob_type, sha1, hdr, &hdrlen); - } else if (write_sha1_file(target, st->st_size, "blob", sha1)) + } else if (write_sha1_file(target, st->st_size, blob_type, sha1)) return error("%s: failed to insert into database", path); free(target);