diff options
Diffstat (limited to 'sha1_file.c')
-rw-r--r-- | sha1_file.c | 133 |
1 files changed, 75 insertions, 58 deletions
diff --git a/sha1_file.c b/sha1_file.c index ac6b5e00b6..7faa8bcd50 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -349,6 +349,7 @@ static void link_alt_odb_entries(const char *alt, const char *ep, int sep, static void read_info_alternates(const char * relative_base, int depth) { char *map; + size_t mapsz; struct stat st; char path[PATH_MAX]; int fd; @@ -361,12 +362,13 @@ static void read_info_alternates(const char * relative_base, int depth) close(fd); return; } - map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + mapsz = xsize_t(st.st_size); + map = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - link_alt_odb_entries(map, map + st.st_size, '\n', relative_base, depth); + link_alt_odb_entries(map, map + mapsz, '\n', relative_base, depth); - munmap(map, st.st_size); + munmap(map, mapsz); } void prepare_alt_odb(void) @@ -430,13 +432,14 @@ void pack_report() pack_mapped, peak_pack_mapped); } -static int check_packed_git_idx(const char *path, unsigned long *idx_size_, - void **idx_map_) +static int check_packed_git_idx(const char *path, + unsigned long *idx_size_, + void **idx_map_) { void *idx_map; uint32_t *index; - unsigned long idx_size; - int nr, i; + size_t idx_size; + uint32_t nr, i; int fd = open(path, O_RDONLY); struct stat st; if (fd < 0) @@ -445,7 +448,11 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, close(fd); return -1; } - idx_size = st.st_size; + idx_size = xsize_t(st.st_size); + if (idx_size < 4 * 256 + 20 + 20) { + close(fd); + return error("index file %s is too small", path); + } idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); @@ -453,25 +460,25 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, *idx_map_ = idx_map; *idx_size_ = idx_size; - /* check index map */ - if (idx_size < 4*256 + 20 + 20) - return error("index file %s is too small", path); - /* a future index format would start with this, as older git * binaries would fail the non-monotonic index check below. * give a nicer warning to the user if we can. */ - if (index[0] == htonl(PACK_IDX_SIGNATURE)) + if (index[0] == htonl(PACK_IDX_SIGNATURE)) { + munmap(idx_map, idx_size); return error("index file %s is a newer version" " and is not supported by this binary" " (try upgrading GIT to a newer version)", path); + } nr = 0; for (i = 0; i < 256; i++) { - unsigned int n = ntohl(index[i]); - if (n < nr) + uint32_t n = ntohl(index[i]); + if (n < nr) { + munmap(idx_map, idx_size); return error("non-monotonic index %s", path); + } nr = n; } @@ -482,8 +489,10 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_, * - 20-byte SHA1 of the packfile * - 20-byte SHA1 file checksum */ - if (idx_size != 4*256 + nr * 24 + 20 + 20) + if (idx_size != 4*256 + nr * 24 + 20 + 20) { + munmap(idx_map, idx_size); return error("wrong index file size in %s", path); + } return 0; } @@ -622,7 +631,7 @@ static int open_packed_git(struct packed_git *p) return -1; } -static int in_window(struct pack_window *win, unsigned long offset) +static int in_window(struct pack_window *win, off_t offset) { /* We must promise at least 20 bytes (one hash) after the * offset is available from this window, otherwise the offset @@ -637,7 +646,7 @@ static int in_window(struct pack_window *win, unsigned long offset) unsigned char* use_pack(struct packed_git *p, struct pack_window **w_cursor, - unsigned long offset, + off_t offset, unsigned int *left) { struct pack_window *win = *w_cursor; @@ -662,11 +671,13 @@ unsigned char* use_pack(struct packed_git *p, } if (!win) { size_t window_align = packed_git_window_size / 2; + off_t len; win = xcalloc(1, sizeof(*win)); win->offset = (offset / window_align) * window_align; - win->len = p->pack_size - win->offset; - if (win->len > packed_git_window_size) - win->len = packed_git_window_size; + len = p->pack_size - win->offset; + if (len > packed_git_window_size) + len = packed_git_window_size; + win->len = (size_t)len; pack_mapped += win->len; while (packed_git_limit < pack_mapped && unuse_one_window(p)) @@ -695,7 +706,7 @@ unsigned char* use_pack(struct packed_git *p, } offset -= win->offset; if (left) - *left = win->len - offset; + *left = win->len - xsize_t(offset); return win->base + offset; } @@ -871,9 +882,9 @@ void *map_sha1_file(const unsigned char *sha1, unsigned long *size) */ sha1_file_open_flag = 0; } - map = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + *size = xsize_t(st.st_size); + map = xmmap(NULL, *size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - *size = st.st_size; return map; } @@ -1053,14 +1064,14 @@ static void *unpack_sha1_file(void *map, unsigned long mapsize, enum object_type return unpack_sha1_rest(&stream, hdr, *size, sha1); } -static unsigned long get_delta_base(struct packed_git *p, +static off_t get_delta_base(struct packed_git *p, struct pack_window **w_curs, - unsigned long *curpos, + off_t *curpos, enum object_type type, - unsigned long delta_obj_offset) + off_t delta_obj_offset) { unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL); - unsigned long base_offset; + off_t base_offset; /* use_pack() assured us we have [base_info, base_info + 20) * as a range that we can look at without walking off the @@ -1096,17 +1107,17 @@ static unsigned long get_delta_base(struct packed_git *p, } /* forward declaration for a mutually recursive function */ -static int packed_object_info(struct packed_git *p, unsigned long offset, +static int packed_object_info(struct packed_git *p, off_t offset, unsigned long *sizep); static int packed_delta_info(struct packed_git *p, struct pack_window **w_curs, - unsigned long curpos, + off_t curpos, enum object_type type, - unsigned long obj_offset, + off_t obj_offset, unsigned long *sizep) { - unsigned long base_offset; + off_t base_offset; base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset); type = packed_object_info(p, base_offset, NULL); @@ -1156,7 +1167,7 @@ static int packed_delta_info(struct packed_git *p, static int unpack_object_header(struct packed_git *p, struct pack_window **w_curs, - unsigned long *curpos, + off_t *curpos, unsigned long *sizep) { unsigned char *base; @@ -1180,14 +1191,15 @@ static int unpack_object_header(struct packed_git *p, } const char *packed_object_info_detail(struct packed_git *p, - unsigned long obj_offset, + off_t obj_offset, unsigned long *size, unsigned long *store_size, unsigned int *delta_chain_length, unsigned char *base_sha1) { struct pack_window *w_curs = NULL; - unsigned long curpos, dummy; + off_t curpos; + unsigned long dummy; unsigned char *next_sha1; enum object_type type; @@ -1211,6 +1223,7 @@ const char *packed_object_info_detail(struct packed_git *p, obj_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); if (*delta_chain_length == 0) { /* TODO: find base_sha1 as pointed by curpos */ + hashclr(base_sha1); } break; case OBJ_REF_DELTA: @@ -1226,11 +1239,12 @@ const char *packed_object_info_detail(struct packed_git *p, } } -static int packed_object_info(struct packed_git *p, unsigned long obj_offset, +static int packed_object_info(struct packed_git *p, off_t obj_offset, unsigned long *sizep) { struct pack_window *w_curs = NULL; - unsigned long size, curpos = obj_offset; + unsigned long size; + off_t curpos = obj_offset; enum object_type type; type = unpack_object_header(p, &w_curs, &curpos, &size); @@ -1258,7 +1272,7 @@ static int packed_object_info(struct packed_git *p, unsigned long obj_offset, static void *unpack_compressed_entry(struct packed_git *p, struct pack_window **w_curs, - unsigned long curpos, + off_t curpos, unsigned long size) { int st; @@ -1289,20 +1303,22 @@ static void *unpack_compressed_entry(struct packed_git *p, static void *unpack_delta_entry(struct packed_git *p, struct pack_window **w_curs, - unsigned long curpos, + off_t curpos, unsigned long delta_size, - unsigned long obj_offset, + off_t obj_offset, enum object_type *type, unsigned long *sizep) { void *delta_data, *result, *base; - unsigned long base_size, base_offset; + unsigned long base_size; + off_t base_offset; base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset); base = unpack_entry(p, base_offset, type, &base_size); if (!base) - die("failed to read delta base object at %lu from %s", - base_offset, p->pack_name); + die("failed to read delta base object" + " at %"PRIuMAX" from %s", + (uintmax_t)base_offset, p->pack_name); delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size); result = patch_delta(base, base_size, @@ -1315,11 +1331,11 @@ static void *unpack_delta_entry(struct packed_git *p, return result; } -void *unpack_entry(struct packed_git *p, unsigned long obj_offset, +void *unpack_entry(struct packed_git *p, off_t obj_offset, enum object_type *type, unsigned long *sizep) { struct pack_window *w_curs = NULL; - unsigned long curpos = obj_offset; + off_t curpos = obj_offset; void *data; *type = unpack_object_header(p, &w_curs, &curpos, sizep); @@ -1342,23 +1358,23 @@ void *unpack_entry(struct packed_git *p, unsigned long obj_offset, return data; } -int num_packed_objects(const struct packed_git *p) +uint32_t num_packed_objects(const struct packed_git *p) { /* See check_packed_git_idx() */ - return (p->index_size - 20 - 20 - 4*256) / 24; + return (uint32_t)((p->index_size - 20 - 20 - 4*256) / 24); } -int nth_packed_object_sha1(const struct packed_git *p, int n, +int nth_packed_object_sha1(const struct packed_git *p, uint32_t n, unsigned char* sha1) { void *index = p->index_base + 256; - if (n < 0 || num_packed_objects(p) <= n) + if (num_packed_objects(p) <= n) return -1; hashcpy(sha1, (unsigned char *) index + (24 * n) + 4); return 0; } -unsigned long find_pack_entry_one(const unsigned char *sha1, +off_t find_pack_entry_one(const unsigned char *sha1, struct packed_git *p) { uint32_t *level1_ofs = p->index_base; @@ -1400,7 +1416,7 @@ static int matches_pack_name(struct packed_git *p, const char *ig) static int find_pack_entry(const unsigned char *sha1, struct pack_entry *e, const char **ignore_packed) { struct packed_git *p; - unsigned long offset; + off_t offset; prepare_packed_git(); @@ -2067,11 +2083,10 @@ int index_pipe(unsigned char *sha1, int fd, const char *type, int write_object) int index_fd(unsigned char *sha1, int fd, struct stat *st, int write_object, enum object_type type, const char *path) { - unsigned long size = st->st_size; - void *buf; + size_t size = xsize_t(st->st_size); + void *buf = NULL; int ret, re_allocated = 0; - buf = ""; if (size) buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); @@ -2111,6 +2126,7 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write { int fd; char *target; + size_t len; switch (st->st_mode & S_IFMT) { case S_IFREG: @@ -2123,16 +2139,17 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, int write path); break; case S_IFLNK: - target = xmalloc(st->st_size+1); - if (readlink(path, target, st->st_size+1) != st->st_size) { + len = xsize_t(st->st_size); + target = xmalloc(len + 1); + if (readlink(path, target, len + 1) != st->st_size) { char *errstr = strerror(errno); free(target); return error("readlink(\"%s\"): %s", path, errstr); } if (!write_object) - hash_sha1_file(target, st->st_size, blob_type, sha1); - else if (write_sha1_file(target, st->st_size, blob_type, sha1)) + hash_sha1_file(target, len, blob_type, sha1); + else if (write_sha1_file(target, len, blob_type, sha1)) return error("%s: failed to insert into database", path); free(target); |