Cast 64 bit off_t to 32 bit size_t
Some systems have sizeof(off_t) == 8 while sizeof(size_t) == 4. This implies that we are able to access and work on files whose maximum length is around 2^63-1 bytes, but we can only malloc or mmap somewhat less than 2^32-1 bytes of memory. On such a system an implicit conversion of off_t to size_t can cause the size_t to wrap, resulting in unexpected and exciting behavior. Right now we are working around all gcc warnings generated by the -Wshorten-64-to-32 option by passing the off_t through xsize_t(). In the future we should make xsize_t on such problematic platforms detect the wrapping and die if such a file is accessed. Signed-off-by: Shawn O. Pearce <spearce@spearce.org> Signed-off-by: Junio C Hamano <junkio@cox.net>maint
							parent
							
								
									6777a59fcd
								
							
						
					
					
						commit
						dc49cd769b
					
				|  | @ -1981,7 +1981,7 @@ static int apply_data(struct patch *patch, struct stat *st, struct cache_entry * | |||
| 		} | ||||
| 	} | ||||
| 	else if (patch->old_name) { | ||||
| 		size = st->st_size; | ||||
| 		size = xsize_t(st->st_size); | ||||
| 		alloc = size + 8192; | ||||
| 		buf = xmalloc(alloc); | ||||
| 		if (read_old_data(st, patch->old_name, &buf, &alloc, &size)) | ||||
|  |  | |||
|  | @ -1963,7 +1963,7 @@ static struct commit *fake_working_tree_commit(const char *path, const char *con | |||
| 				die("Cannot lstat %s", path); | ||||
| 			read_from = path; | ||||
| 		} | ||||
| 		fin_size = st.st_size; | ||||
| 		fin_size = xsize_t(st.st_size); | ||||
| 		buf = xmalloc(fin_size+1); | ||||
| 		mode = canon_mode(st.st_mode); | ||||
| 		switch (st.st_mode & S_IFMT) { | ||||
|  |  | |||
|  | @ -44,7 +44,7 @@ static void count_objects(DIR *d, char *path, int len, int verbose, | |||
| 			if (lstat(path, &st) || !S_ISREG(st.st_mode)) | ||||
| 				bad = 1; | ||||
| 			else | ||||
| 				(*loose_size) += st.st_blocks; | ||||
| 				(*loose_size) += xsize_t(st.st_blocks); | ||||
| 		} | ||||
| 		if (bad) { | ||||
| 			if (verbose) { | ||||
|  |  | |||
|  | @ -122,6 +122,8 @@ static int grep_file(struct grep_opt *opt, const char *filename) | |||
| 	struct stat st; | ||||
| 	int i; | ||||
| 	char *data; | ||||
| 	size_t sz; | ||||
|  | ||||
| 	if (lstat(filename, &st) < 0) { | ||||
| 	err_ret: | ||||
| 		if (errno != ENOENT) | ||||
|  | @ -132,11 +134,12 @@ static int grep_file(struct grep_opt *opt, const char *filename) | |||
| 		return 0; /* empty file -- no grep hit */ | ||||
| 	if (!S_ISREG(st.st_mode)) | ||||
| 		return 0; | ||||
| 	sz = xsize_t(st.st_size); | ||||
| 	i = open(filename, O_RDONLY); | ||||
| 	if (i < 0) | ||||
| 		goto err_ret; | ||||
| 	data = xmalloc(st.st_size + 1); | ||||
| 	if (st.st_size != read_in_full(i, data, st.st_size)) { | ||||
| 	data = xmalloc(sz + 1); | ||||
| 	if (st.st_size != read_in_full(i, data, sz)) { | ||||
| 		error("'%s': short read %s", filename, strerror(errno)); | ||||
| 		close(i); | ||||
| 		free(data); | ||||
|  | @ -145,7 +148,7 @@ static int grep_file(struct grep_opt *opt, const char *filename) | |||
| 	close(i); | ||||
| 	if (opt->relative && opt->prefix_length) | ||||
| 		filename += opt->prefix_length; | ||||
| 	i = grep_buffer(opt, filename, data, st.st_size); | ||||
| 	i = grep_buffer(opt, filename, data, sz); | ||||
| 	free(data); | ||||
| 	return i; | ||||
| } | ||||
|  |  | |||
|  | @ -684,7 +684,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, | |||
| 			goto deleted_file; | ||||
|  | ||||
| 		if (S_ISLNK(st.st_mode)) { | ||||
| 			size_t len = st.st_size; | ||||
| 			size_t len = xsize_t(st.st_size); | ||||
| 			result_size = len; | ||||
| 			result = xmalloc(len + 1); | ||||
| 			if (result_size != readlink(elem->path, result, len)) { | ||||
|  | @ -697,7 +697,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, | |||
| 		} | ||||
| 		else if (0 <= (fd = open(elem->path, O_RDONLY)) && | ||||
| 			 !fstat(fd, &st)) { | ||||
| 			size_t len = st.st_size; | ||||
| 			size_t len = xsize_t(st.st_size); | ||||
| 			size_t sz = 0; | ||||
| 			int is_file, i; | ||||
|  | ||||
|  |  | |||
							
								
								
									
										28
									
								
								config.c
								
								
								
								
							
							
						
						
									
										28
									
								
								config.c
								
								
								
								
							|  | @ -431,7 +431,7 @@ static struct { | |||
| 	int do_not_match; | ||||
| 	regex_t* value_regex; | ||||
| 	int multi_replace; | ||||
| 	off_t offset[MAX_MATCHES]; | ||||
| 	size_t offset[MAX_MATCHES]; | ||||
| 	enum { START, SECTION_SEEN, SECTION_END_SEEN, KEY_SEEN } state; | ||||
| 	int seen; | ||||
| } store; | ||||
|  | @ -579,11 +579,11 @@ static int store_write_pair(int fd, const char* key, const char* value) | |||
| 	return 1; | ||||
| } | ||||
|  | ||||
| static int find_beginning_of_line(const char* contents, int size, | ||||
| 	int offset_, int* found_bracket) | ||||
| static ssize_t find_beginning_of_line(const char* contents, size_t size, | ||||
| 	size_t offset_, int* found_bracket) | ||||
| { | ||||
| 	int equal_offset = size, bracket_offset = size; | ||||
| 	int offset; | ||||
| 	size_t equal_offset = size, bracket_offset = size; | ||||
| 	ssize_t offset; | ||||
|  | ||||
| 	for (offset = offset_-2; offset > 0  | ||||
| 			&& contents[offset] != '\n'; offset--) | ||||
|  | @ -727,7 +727,8 @@ int git_config_set_multivar(const char* key, const char* value, | |||
| 	} else { | ||||
| 		struct stat st; | ||||
| 		char* contents; | ||||
| 		int i, copy_begin, copy_end, new_line = 0; | ||||
| 		size_t contents_sz, copy_begin, copy_end; | ||||
| 		int i, new_line = 0; | ||||
|  | ||||
| 		if (value_regex == NULL) | ||||
| 			store.value_regex = NULL; | ||||
|  | @ -784,7 +785,8 @@ int git_config_set_multivar(const char* key, const char* value, | |||
| 		} | ||||
|  | ||||
| 		fstat(in_fd, &st); | ||||
| 		contents = xmmap(NULL, st.st_size, PROT_READ, | ||||
| 		contents_sz = xsize_t(st.st_size); | ||||
| 		contents = xmmap(NULL, contents_sz, PROT_READ, | ||||
| 			MAP_PRIVATE, in_fd, 0); | ||||
| 		close(in_fd); | ||||
|  | ||||
|  | @ -793,12 +795,12 @@ int git_config_set_multivar(const char* key, const char* value, | |||
|  | ||||
| 		for (i = 0, copy_begin = 0; i < store.seen; i++) { | ||||
| 			if (store.offset[i] == 0) { | ||||
| 				store.offset[i] = copy_end = st.st_size; | ||||
| 				store.offset[i] = copy_end = contents_sz; | ||||
| 			} else if (store.state != KEY_SEEN) { | ||||
| 				copy_end = store.offset[i]; | ||||
| 			} else | ||||
| 				copy_end = find_beginning_of_line( | ||||
| 					contents, st.st_size, | ||||
| 					contents, contents_sz, | ||||
| 					store.offset[i]-2, &new_line); | ||||
|  | ||||
| 			/* write the first part of the config */ | ||||
|  | @ -825,13 +827,13 @@ int git_config_set_multivar(const char* key, const char* value, | |||
| 		} | ||||
|  | ||||
| 		/* write the rest of the config */ | ||||
| 		if (copy_begin < st.st_size) | ||||
| 		if (copy_begin < contents_sz) | ||||
| 			if (write_in_full(fd, contents + copy_begin, | ||||
| 					  st.st_size - copy_begin) < | ||||
| 			    st.st_size - copy_begin) | ||||
| 					  contents_sz - copy_begin) < | ||||
| 			    contents_sz - copy_begin) | ||||
| 				goto write_err_out; | ||||
|  | ||||
| 		munmap(contents, st.st_size); | ||||
| 		munmap(contents, contents_sz); | ||||
| 		unlink(config_filename); | ||||
| 	} | ||||
|  | ||||
|  |  | |||
							
								
								
									
										9
									
								
								diff.c
								
								
								
								
							
							
						
						
									
										9
									
								
								diff.c
								
								
								
								
							|  | @ -1399,7 +1399,7 @@ int diff_populate_filespec(struct diff_filespec *s, int size_only) | |||
| 				return err; | ||||
| 			} | ||||
| 		} | ||||
| 		s->size = st.st_size; | ||||
| 		s->size = xsize_t(st.st_size); | ||||
| 		if (!s->size) | ||||
| 			goto empty; | ||||
| 		if (size_only) | ||||
|  | @ -1515,12 +1515,13 @@ static void prepare_temp_file(const char *name, | |||
| 		if (S_ISLNK(st.st_mode)) { | ||||
| 			int ret; | ||||
| 			char buf[PATH_MAX + 1]; /* ought to be SYMLINK_MAX */ | ||||
| 			size_t sz = xsize_t(st.st_size); | ||||
| 			if (sizeof(buf) <= st.st_size) | ||||
| 				die("symlink too long: %s", name); | ||||
| 			ret = readlink(name, buf, st.st_size); | ||||
| 			ret = readlink(name, buf, sz); | ||||
| 			if (ret < 0) | ||||
| 				die("readlink(%s)", name); | ||||
| 			prep_temp_blob(temp, buf, st.st_size, | ||||
| 			prep_temp_blob(temp, buf, sz, | ||||
| 				       (one->sha1_valid ? | ||||
| 					one->sha1 : null_sha1), | ||||
| 				       (one->sha1_valid ? | ||||
|  | @ -2138,7 +2139,7 @@ static int parse_num(const char **cp_p) | |||
| 	/* user says num divided by scale and we say internally that | ||||
| 	 * is MAX_SCORE * num / scale. | ||||
| 	 */ | ||||
| 	return (num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale); | ||||
| 	return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale)); | ||||
| } | ||||
|  | ||||
| int diff_scoreopt_parse(const char *opt) | ||||
|  |  | |||
|  | @ -89,7 +89,7 @@ static int should_break(struct diff_filespec *src, | |||
| 	 * merge the surviving pair together if the score is | ||||
| 	 * less than the minimum, after rename/copy runs. | ||||
| 	 */ | ||||
| 	*merge_score_p = src_removed * MAX_SCORE / src->size; | ||||
| 	*merge_score_p = (int)(src_removed * MAX_SCORE / src->size); | ||||
|  | ||||
| 	/* Extent of damage, which counts both inserts and | ||||
| 	 * deletes. | ||||
|  |  | |||
|  | @ -14,6 +14,7 @@ static void prepare_order(const char *orderfile) | |||
| 	void *map; | ||||
| 	char *cp, *endp; | ||||
| 	struct stat st; | ||||
| 	size_t sz; | ||||
|  | ||||
| 	if (order) | ||||
| 		return; | ||||
|  | @ -25,11 +26,12 @@ static void prepare_order(const char *orderfile) | |||
| 		close(fd); | ||||
| 		return; | ||||
| 	} | ||||
| 	map = mmap(NULL, st.st_size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
| 	sz = xsize_t(st.st_size); | ||||
| 	map = mmap(NULL, sz, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
| 	close(fd); | ||||
| 	if (map == MAP_FAILED) | ||||
| 		return; | ||||
| 	endp = (char *) map + st.st_size; | ||||
| 	endp = (char *) map + sz; | ||||
| 	for (pass = 0; pass < 2; pass++) { | ||||
| 		cnt = 0; | ||||
| 		cp = map; | ||||
|  |  | |||
|  | @ -172,7 +172,8 @@ static int estimate_similarity(struct diff_filespec *src, | |||
| 		return 0; /* error but caught downstream */ | ||||
|  | ||||
|  | ||||
| 	delta_limit = base_size * (MAX_SCORE-minimum_score) / MAX_SCORE; | ||||
| 	delta_limit = (unsigned long) | ||||
| 		(base_size * (MAX_SCORE-minimum_score) / MAX_SCORE); | ||||
| 	if (diffcore_count_changes(src->data, src->size, | ||||
| 				   dst->data, dst->size, | ||||
| 				   &src->cnt_data, &dst->cnt_data, | ||||
|  | @ -186,7 +187,7 @@ static int estimate_similarity(struct diff_filespec *src, | |||
| 	if (!dst->size) | ||||
| 		score = 0; /* should not happen */ | ||||
| 	else | ||||
| 		score = src_copied * MAX_SCORE / max_size; | ||||
| 		score = (int)(src_copied * MAX_SCORE / max_size); | ||||
| 	return score; | ||||
| } | ||||
|  | ||||
|  | @ -297,7 +298,7 @@ void diffcore_rename(struct diff_options *options) | |||
| 				struct diff_filespec *one = rename_src[j].one; | ||||
| 				if (!is_exact_match(one, two, contents_too)) | ||||
| 					continue; | ||||
| 				record_rename_pair(i, j, MAX_SCORE); | ||||
| 				record_rename_pair(i, j, (int)MAX_SCORE); | ||||
| 				rename_count++; | ||||
| 				break; /* we are done with this entry */ | ||||
| 			} | ||||
|  |  | |||
							
								
								
									
										4
									
								
								dir.c
								
								
								
								
							
							
						
						
									
										4
									
								
								dir.c
								
								
								
								
							|  | @ -130,13 +130,13 @@ static int add_excludes_from_file_1(const char *fname, | |||
| { | ||||
| 	struct stat st; | ||||
| 	int fd, i; | ||||
| 	long size; | ||||
| 	size_t size; | ||||
| 	char *buf, *entry; | ||||
|  | ||||
| 	fd = open(fname, O_RDONLY); | ||||
| 	if (fd < 0 || fstat(fd, &st) < 0) | ||||
| 		goto err; | ||||
| 	size = st.st_size; | ||||
| 	size = xsize_t(st.st_size); | ||||
| 	if (size == 0) { | ||||
| 		close(fd); | ||||
| 		return 0; | ||||
|  |  | |||
|  | @ -258,6 +258,11 @@ static inline ssize_t xwrite(int fd, const void *buf, size_t len) | |||
| 	} | ||||
| } | ||||
|  | ||||
| static inline size_t xsize_t(off_t len) | ||||
| { | ||||
| 	return (size_t)len; | ||||
| } | ||||
|  | ||||
| static inline int has_extension(const char *filename, const char *ext) | ||||
| { | ||||
| 	size_t len = strlen(filename); | ||||
|  |  | |||
|  | @ -66,7 +66,7 @@ static int ce_compare_data(struct cache_entry *ce, struct stat *st) | |||
| 	return match; | ||||
| } | ||||
|  | ||||
| static int ce_compare_link(struct cache_entry *ce, unsigned long expected_size) | ||||
| static int ce_compare_link(struct cache_entry *ce, size_t expected_size) | ||||
| { | ||||
| 	int match = -1; | ||||
| 	char *target; | ||||
|  | @ -101,7 +101,7 @@ static int ce_modified_check_fs(struct cache_entry *ce, struct stat *st) | |||
| 			return DATA_CHANGED; | ||||
| 		break; | ||||
| 	case S_IFLNK: | ||||
| 		if (ce_compare_link(ce, st->st_size)) | ||||
| 		if (ce_compare_link(ce, xsize_t(st->st_size))) | ||||
| 			return DATA_CHANGED; | ||||
| 		break; | ||||
| 	default: | ||||
|  | @ -797,7 +797,7 @@ int read_cache_from(const char *path) | |||
| 	} | ||||
|  | ||||
| 	if (!fstat(fd, &st)) { | ||||
| 		cache_mmap_size = st.st_size; | ||||
| 		cache_mmap_size = xsize_t(st.st_size); | ||||
| 		errno = EINVAL; | ||||
| 		if (cache_mmap_size >= sizeof(struct cache_header) + 20) | ||||
| 			cache_mmap = xmmap(NULL, cache_mmap_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0); | ||||
|  |  | |||
							
								
								
									
										8
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										8
									
								
								refs.c
								
								
								
								
							|  | @ -1075,6 +1075,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * | |||
| 	unsigned long date; | ||||
| 	unsigned char logged_sha1[20]; | ||||
| 	void *log_mapped; | ||||
| 	size_t mapsz; | ||||
|  | ||||
| 	logfile = git_path("logs/%s", ref); | ||||
| 	logfd = open(logfile, O_RDONLY, 0); | ||||
|  | @ -1083,7 +1084,8 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * | |||
| 	fstat(logfd, &st); | ||||
| 	if (!st.st_size) | ||||
| 		die("Log %s is empty.", logfile); | ||||
| 	log_mapped = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, logfd, 0); | ||||
| 	mapsz = xsize_t(st.st_size); | ||||
| 	log_mapped = xmmap(NULL, mapsz, PROT_READ, MAP_PRIVATE, logfd, 0); | ||||
| 	logdata = log_mapped; | ||||
| 	close(logfd); | ||||
|  | ||||
|  | @ -1136,7 +1138,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * | |||
| 						logfile, show_rfc2822_date(date, tz)); | ||||
| 				} | ||||
| 			} | ||||
| 			munmap(log_mapped, st.st_size); | ||||
| 			munmap(log_mapped, mapsz); | ||||
| 			return 0; | ||||
| 		} | ||||
| 		lastrec = rec; | ||||
|  | @ -1155,7 +1157,7 @@ int read_ref_at(const char *ref, unsigned long at_time, int cnt, unsigned char * | |||
| 		die("Log %s is corrupt.", logfile); | ||||
| 	if (msg) | ||||
| 		*msg = ref_msg(logdata, logend); | ||||
| 	munmap(log_mapped, st.st_size); | ||||
| 	munmap(log_mapped, mapsz); | ||||
|  | ||||
| 	if (cutoff_time) | ||||
| 		*cutoff_time = date; | ||||
|  |  | |||
							
								
								
									
										40
									
								
								sha1_file.c
								
								
								
								
							
							
						
						
									
										40
									
								
								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) | ||||
|  | @ -436,7 +438,7 @@ static int check_packed_git_idx(const char *path, | |||
| { | ||||
| 	void *idx_map; | ||||
| 	uint32_t *index; | ||||
| 	unsigned long idx_size; | ||||
| 	size_t idx_size; | ||||
| 	uint32_t nr, i; | ||||
| 	int fd = open(path, O_RDONLY); | ||||
| 	struct stat st; | ||||
|  | @ -446,7 +448,7 @@ static int check_packed_git_idx(const char *path, | |||
| 		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); | ||||
|  | @ -669,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)) | ||||
|  | @ -702,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; | ||||
| } | ||||
|  | ||||
|  | @ -878,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; | ||||
| } | ||||
|  | ||||
|  | @ -1346,7 +1350,7 @@ void *unpack_entry(struct packed_git *p, off_t obj_offset, | |||
| 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, uint32_t n, | ||||
|  | @ -2068,7 +2072,7 @@ 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; | ||||
| 	size_t size = xsize_t(st->st_size); | ||||
| 	void *buf = NULL; | ||||
| 	int ret, re_allocated = 0; | ||||
|  | ||||
|  | @ -2111,6 +2115,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 +2128,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); | ||||
|  |  | |||
|  | @ -107,16 +107,18 @@ int read_mmfile(mmfile_t *ptr, const char *filename) | |||
| { | ||||
| 	struct stat st; | ||||
| 	FILE *f; | ||||
| 	size_t sz; | ||||
|  | ||||
| 	if (stat(filename, &st)) | ||||
| 		return error("Could not stat %s", filename); | ||||
| 	if ((f = fopen(filename, "rb")) == NULL) | ||||
| 		return error("Could not open %s", filename); | ||||
| 	ptr->ptr = xmalloc(st.st_size); | ||||
| 	if (fread(ptr->ptr, st.st_size, 1, f) != 1) | ||||
| 	sz = xsize_t(st.st_size); | ||||
| 	ptr->ptr = xmalloc(sz); | ||||
| 	if (fread(ptr->ptr, sz, 1, f) != 1) | ||||
| 		return error("Could not read %s", filename); | ||||
| 	fclose(f); | ||||
| 	ptr->size = st.st_size; | ||||
| 	ptr->size = sz; | ||||
| 	return 0; | ||||
| } | ||||
|  | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Shawn O. Pearce
						Shawn O. Pearce