X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=sha1_file.c;h=f2d33afb27f6c73ad6c177098fe2f2674add7fbe;hb=61c2bcbd11e3b66a328b3850c01592e5dc1c67bb;hp=9cab99ae7c2b1e59db7be26d79d287254db21211;hpb=155d12912fec6c60ead6d6c1febda5fa6e6eb128;p=git.git diff --git a/sha1_file.c b/sha1_file.c index 9cab99ae..f2d33afb 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__)) @@ -247,6 +251,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, for ( ; cp < ep && *cp != sep; cp++) ; if (last != cp) { + struct stat st; struct alternate_object_database *alt; /* 43 = 40-byte + 2 '/' + terminating NUL */ int pfxlen = cp - last; @@ -269,9 +274,19 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, } else memcpy(ent->base, last, pfxlen); + ent->name = ent->base + pfxlen + 1; - ent->base[pfxlen] = ent->base[pfxlen + 3] = '/'; - ent->base[entlen-1] = 0; + ent->base[pfxlen + 3] = '/'; + ent->base[pfxlen] = ent->base[entlen-1] = 0; + + /* Detect cases where alternate disappeared */ + if (stat(ent->base, &st) || !S_ISDIR(st.st_mode)) { + error("object directory %s does not exist; " + "check .git/objects/info/alternates.", + ent->base); + goto bad; + } + ent->base[pfxlen] = '/'; /* Prevent the common mistake of listing the same * thing twice, or object directory itself. @@ -552,7 +567,9 @@ static void prepare_packed_git_one(char *objdir, int local) len = strlen(path); dir = opendir(path); if (!dir) { - fprintf(stderr, "unable to open object pack directory: %s: %s\n", path, strerror(errno)); + if (errno != ENOENT) + error("unable to open object pack directory: %s: %s", + path, strerror(errno)); return; } path[len++] = '/'; @@ -791,10 +808,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; @@ -855,17 +874,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; @@ -881,16 +902,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", @@ -921,16 +942,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", @@ -960,6 +981,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); @@ -977,14 +1008,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); @@ -1056,16 +1079,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; @@ -1226,9 +1249,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); @@ -1500,7 +1523,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)); @@ -1548,7 +1572,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)); @@ -1609,7 +1633,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 { @@ -1636,7 +1660,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 { @@ -1674,9 +1698,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);