Merge branch 'ar/mksnpath'
* ar/mksnpath: Use git_pathdup instead of xstrdup(git_path(...)) git_pathdup: returns xstrdup-ed copy of the formatted path Fix potentially dangerous use of git_path in ref.c Add git_snpath: a .git path formatting routine with output buffer Fix potentially dangerous uses of mkpath and git_path Fix potentially dangerous uses of mkpath and git_path Fix mkpath abuse in dwim_ref and dwim_log of sha1_name.c Add mksnpath which allows you to specify the output buffer Conflicts: builtin-revert.cmaint
						commit
						a1a846a19e
					
				|  | @ -2841,8 +2841,8 @@ static void create_one_file(char *path, unsigned mode, const char *buf, unsigned | ||||||
| 		unsigned int nr = getpid(); | 		unsigned int nr = getpid(); | ||||||
|  |  | ||||||
| 		for (;;) { | 		for (;;) { | ||||||
| 			const char *newpath; | 			char newpath[PATH_MAX]; | ||||||
| 			newpath = mkpath("%s~%u", path, nr); | 			mksnpath(newpath, sizeof(newpath), "%s~%u", path, nr); | ||||||
| 			if (!try_create_file(newpath, mode, buf, size)) { | 			if (!try_create_file(newpath, mode, buf, size)) { | ||||||
| 				if (!rename(newpath, path)) | 				if (!rename(newpath, path)) | ||||||
| 					return; | 					return; | ||||||
|  |  | ||||||
|  | @ -84,7 +84,7 @@ static int get_value(const char* key_, const char* regex_) | ||||||
| 	local = config_exclusive_filename; | 	local = config_exclusive_filename; | ||||||
| 	if (!local) { | 	if (!local) { | ||||||
| 		const char *home = getenv("HOME"); | 		const char *home = getenv("HOME"); | ||||||
| 		local = repo_config = xstrdup(git_path("config")); | 		local = repo_config = git_pathdup("config"); | ||||||
| 		if (git_config_global() && home) | 		if (git_config_global() && home) | ||||||
| 			global = xstrdup(mkpath("%s/.gitconfig", home)); | 			global = xstrdup(mkpath("%s/.gitconfig", home)); | ||||||
| 		if (git_config_system()) | 		if (git_config_system()) | ||||||
|  |  | ||||||
|  | @ -620,14 +620,16 @@ static char *get_short_ref(struct refinfo *ref) | ||||||
| 		for (j = 0; j < i; j++) { | 		for (j = 0; j < i; j++) { | ||||||
| 			const char *rule = ref_rev_parse_rules[j]; | 			const char *rule = ref_rev_parse_rules[j]; | ||||||
| 			unsigned char short_objectname[20]; | 			unsigned char short_objectname[20]; | ||||||
|  | 			char refname[PATH_MAX]; | ||||||
|  |  | ||||||
| 			/* | 			/* | ||||||
| 			 * the short name is ambiguous, if it resolves | 			 * the short name is ambiguous, if it resolves | ||||||
| 			 * (with this previous rule) to a valid ref | 			 * (with this previous rule) to a valid ref | ||||||
| 			 * read_ref() returns 0 on success | 			 * read_ref() returns 0 on success | ||||||
| 			 */ | 			 */ | ||||||
| 			if (!read_ref(mkpath(rule, short_name_len, short_name), | 			mksnpath(refname, sizeof(refname), | ||||||
| 				      short_objectname)) | 				 rule, short_name_len, short_name); | ||||||
|  | 			if (!read_ref(refname, short_objectname)) | ||||||
| 				break; | 				break; | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -277,11 +277,11 @@ static int expire_reflog(const char *ref, const unsigned char *sha1, int unused, | ||||||
| 	lock = lock_any_ref_for_update(ref, sha1, 0); | 	lock = lock_any_ref_for_update(ref, sha1, 0); | ||||||
| 	if (!lock) | 	if (!lock) | ||||||
| 		return error("cannot lock ref '%s'", ref); | 		return error("cannot lock ref '%s'", ref); | ||||||
| 	log_file = xstrdup(git_path("logs/%s", ref)); | 	log_file = git_pathdup("logs/%s", ref); | ||||||
| 	if (!file_exists(log_file)) | 	if (!file_exists(log_file)) | ||||||
| 		goto finish; | 		goto finish; | ||||||
| 	if (!cmd->dry_run) { | 	if (!cmd->dry_run) { | ||||||
| 		newlog_path = xstrdup(git_path("logs/%s.lock", ref)); | 		newlog_path = git_pathdup("logs/%s.lock", ref); | ||||||
| 		cb.newlog = fopen(newlog_path, "w"); | 		cb.newlog = fopen(newlog_path, "w"); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -251,7 +251,7 @@ static int revert_or_cherry_pick(int argc, const char **argv) | ||||||
| 	int i, index_fd, clean; | 	int i, index_fd, clean; | ||||||
| 	char *oneline, *reencoded_message = NULL; | 	char *oneline, *reencoded_message = NULL; | ||||||
| 	const char *message, *encoding; | 	const char *message, *encoding; | ||||||
| 	char *defmsg = xstrdup(git_path("MERGE_MSG")); | 	char *defmsg = git_pathdup("MERGE_MSG"); | ||||||
| 	struct merge_options o; | 	struct merge_options o; | ||||||
| 	struct tree *result, *next_tree, *base_tree, *head_tree; | 	struct tree *result, *next_tree, *base_tree, *head_tree; | ||||||
| 	static struct lock_file index_lock; | 	static struct lock_file index_lock; | ||||||
|  |  | ||||||
|  | @ -283,7 +283,7 @@ static void create_tag(const unsigned char *object, const char *tag, | ||||||
| 		int fd; | 		int fd; | ||||||
|  |  | ||||||
| 		/* write the template message before editing: */ | 		/* write the template message before editing: */ | ||||||
| 		path = xstrdup(git_path("TAG_EDITMSG")); | 		path = git_pathdup("TAG_EDITMSG"); | ||||||
| 		fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); | 		fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0600); | ||||||
| 		if (fd < 0) | 		if (fd < 0) | ||||||
| 			die("could not create file '%s': %s", | 			die("could not create file '%s': %s", | ||||||
|  |  | ||||||
							
								
								
									
										7
									
								
								cache.h
								
								
								
								
							
							
						
						
									
										7
									
								
								cache.h
								
								
								
								
							|  | @ -495,6 +495,13 @@ extern int check_repository_format(void); | ||||||
| #define DATA_CHANGED    0x0020 | #define DATA_CHANGED    0x0020 | ||||||
| #define TYPE_CHANGED    0x0040 | #define TYPE_CHANGED    0x0040 | ||||||
|  |  | ||||||
|  | extern char *mksnpath(char *buf, size_t n, const char *fmt, ...) | ||||||
|  | 	__attribute__((format (printf, 3, 4))); | ||||||
|  | extern char *git_snpath(char *buf, size_t n, const char *fmt, ...) | ||||||
|  | 	__attribute__((format (printf, 3, 4))); | ||||||
|  | extern char *git_pathdup(const char *fmt, ...) | ||||||
|  | 	__attribute__((format (printf, 1, 2))); | ||||||
|  |  | ||||||
| /* Return a statically allocated filename matching the sha1 signature */ | /* Return a statically allocated filename matching the sha1 signature */ | ||||||
| extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | extern char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | ||||||
| extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | extern char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); | ||||||
|  |  | ||||||
							
								
								
									
										6
									
								
								config.c
								
								
								
								
							
							
						
						
									
										6
									
								
								config.c
								
								
								
								
							|  | @ -649,7 +649,7 @@ int git_config(config_fn_t fn, void *data) | ||||||
| 		free(user_config); | 		free(user_config); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	repo_config = xstrdup(git_path("config")); | 	repo_config = git_pathdup("config"); | ||||||
| 	ret += git_config_from_file(fn, repo_config, data); | 	ret += git_config_from_file(fn, repo_config, data); | ||||||
| 	free(repo_config); | 	free(repo_config); | ||||||
| 	return ret; | 	return ret; | ||||||
|  | @ -889,7 +889,7 @@ int git_config_set_multivar(const char* key, const char* value, | ||||||
| 	if (config_exclusive_filename) | 	if (config_exclusive_filename) | ||||||
| 		config_filename = xstrdup(config_exclusive_filename); | 		config_filename = xstrdup(config_exclusive_filename); | ||||||
| 	else | 	else | ||||||
| 		config_filename = xstrdup(git_path("config")); | 		config_filename = git_pathdup("config"); | ||||||
|  |  | ||||||
| 	/* | 	/* | ||||||
| 	 * Since "key" actually contains the section name and the real | 	 * Since "key" actually contains the section name and the real | ||||||
|  | @ -1149,7 +1149,7 @@ int git_config_rename_section(const char *old_name, const char *new_name) | ||||||
| 	if (config_exclusive_filename) | 	if (config_exclusive_filename) | ||||||
| 		config_filename = xstrdup(config_exclusive_filename); | 		config_filename = xstrdup(config_exclusive_filename); | ||||||
| 	else | 	else | ||||||
| 		config_filename = xstrdup(git_path("config")); | 		config_filename = git_pathdup("config"); | ||||||
| 	out_fd = hold_lock_file_for_update(lock, config_filename, 0); | 	out_fd = hold_lock_file_for_update(lock, config_filename, 0); | ||||||
| 	if (out_fd < 0) { | 	if (out_fd < 0) { | ||||||
| 		ret = error("could not lock config file %s", config_filename); | 		ret = error("could not lock config file %s", config_filename); | ||||||
|  |  | ||||||
|  | @ -71,7 +71,7 @@ static void setup_git_env(void) | ||||||
| 	} | 	} | ||||||
| 	git_graft_file = getenv(GRAFT_ENVIRONMENT); | 	git_graft_file = getenv(GRAFT_ENVIRONMENT); | ||||||
| 	if (!git_graft_file) | 	if (!git_graft_file) | ||||||
| 		git_graft_file = xstrdup(git_path("info/grafts")); | 		git_graft_file = git_pathdup("info/grafts"); | ||||||
| } | } | ||||||
|  |  | ||||||
| int is_bare_repository(void) | int is_bare_repository(void) | ||||||
|  |  | ||||||
							
								
								
									
										54
									
								
								path.c
								
								
								
								
							
							
						
						
									
										54
									
								
								path.c
								
								
								
								
							|  | @ -32,6 +32,60 @@ static char *cleanup_path(char *path) | ||||||
| 	return path; | 	return path; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | char *mksnpath(char *buf, size_t n, const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list args; | ||||||
|  | 	unsigned len; | ||||||
|  |  | ||||||
|  | 	va_start(args, fmt); | ||||||
|  | 	len = vsnprintf(buf, n, fmt, args); | ||||||
|  | 	va_end(args); | ||||||
|  | 	if (len >= n) { | ||||||
|  | 		snprintf(buf, n, bad_path); | ||||||
|  | 		return buf; | ||||||
|  | 	} | ||||||
|  | 	return cleanup_path(buf); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | static char *git_vsnpath(char *buf, size_t n, const char *fmt, va_list args) | ||||||
|  | { | ||||||
|  | 	const char *git_dir = get_git_dir(); | ||||||
|  | 	size_t len; | ||||||
|  |  | ||||||
|  | 	len = strlen(git_dir); | ||||||
|  | 	if (n < len + 1) | ||||||
|  | 		goto bad; | ||||||
|  | 	memcpy(buf, git_dir, len); | ||||||
|  | 	if (len && !is_dir_sep(git_dir[len-1])) | ||||||
|  | 		buf[len++] = '/'; | ||||||
|  | 	len += vsnprintf(buf + len, n - len, fmt, args); | ||||||
|  | 	if (len >= n) | ||||||
|  | 		goto bad; | ||||||
|  | 	return cleanup_path(buf); | ||||||
|  | bad: | ||||||
|  | 	snprintf(buf, n, bad_path); | ||||||
|  | 	return buf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char *git_snpath(char *buf, size_t n, const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	va_list args; | ||||||
|  | 	va_start(args, fmt); | ||||||
|  | 	(void)git_vsnpath(buf, n, fmt, args); | ||||||
|  | 	va_end(args); | ||||||
|  | 	return buf; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | char *git_pathdup(const char *fmt, ...) | ||||||
|  | { | ||||||
|  | 	char path[PATH_MAX]; | ||||||
|  | 	va_list args; | ||||||
|  | 	va_start(args, fmt); | ||||||
|  | 	(void)git_vsnpath(path, sizeof(path), fmt, args); | ||||||
|  | 	va_end(args); | ||||||
|  | 	return xstrdup(path); | ||||||
|  | } | ||||||
|  |  | ||||||
| char *mkpath(const char *fmt, ...) | char *mkpath(const char *fmt, ...) | ||||||
| { | { | ||||||
| 	va_list args; | 	va_list args; | ||||||
|  |  | ||||||
							
								
								
									
										10
									
								
								refs.c
								
								
								
								
							
							
						
						
									
										10
									
								
								refs.c
								
								
								
								
							|  | @ -413,7 +413,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * | ||||||
| 		*flag = 0; | 		*flag = 0; | ||||||
|  |  | ||||||
| 	for (;;) { | 	for (;;) { | ||||||
| 		const char *path = git_path("%s", ref); | 		char path[PATH_MAX]; | ||||||
| 		struct stat st; | 		struct stat st; | ||||||
| 		char *buf; | 		char *buf; | ||||||
| 		int fd; | 		int fd; | ||||||
|  | @ -421,6 +421,7 @@ const char *resolve_ref(const char *ref, unsigned char *sha1, int reading, int * | ||||||
| 		if (--depth < 0) | 		if (--depth < 0) | ||||||
| 			return NULL; | 			return NULL; | ||||||
|  |  | ||||||
|  | 		git_snpath(path, sizeof(path), "%s", ref); | ||||||
| 		/* Special case: non-existing file. */ | 		/* Special case: non-existing file. */ | ||||||
| 		if (lstat(path, &st) < 0) { | 		if (lstat(path, &st) < 0) { | ||||||
| 			struct ref_list *list = get_packed_refs(); | 			struct ref_list *list = get_packed_refs(); | ||||||
|  | @ -1142,13 +1143,14 @@ static int log_ref_write(const char *ref_name, const unsigned char *old_sha1, | ||||||
| 	int logfd, written, oflags = O_APPEND | O_WRONLY; | 	int logfd, written, oflags = O_APPEND | O_WRONLY; | ||||||
| 	unsigned maxlen, len; | 	unsigned maxlen, len; | ||||||
| 	int msglen; | 	int msglen; | ||||||
| 	char *log_file, *logrec; | 	char log_file[PATH_MAX]; | ||||||
|  | 	char *logrec; | ||||||
| 	const char *committer; | 	const char *committer; | ||||||
|  |  | ||||||
| 	if (log_all_ref_updates < 0) | 	if (log_all_ref_updates < 0) | ||||||
| 		log_all_ref_updates = !is_bare_repository(); | 		log_all_ref_updates = !is_bare_repository(); | ||||||
|  |  | ||||||
| 	log_file = git_path("logs/%s", ref_name); | 	git_snpath(log_file, sizeof(log_file), "logs/%s", ref_name); | ||||||
|  |  | ||||||
| 	if (log_all_ref_updates && | 	if (log_all_ref_updates && | ||||||
| 	    (!prefixcmp(ref_name, "refs/heads/") || | 	    (!prefixcmp(ref_name, "refs/heads/") || | ||||||
|  | @ -1277,7 +1279,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master, | ||||||
| 	const char *lockpath; | 	const char *lockpath; | ||||||
| 	char ref[1000]; | 	char ref[1000]; | ||||||
| 	int fd, len, written; | 	int fd, len, written; | ||||||
| 	char *git_HEAD = xstrdup(git_path("%s", ref_target)); | 	char *git_HEAD = git_pathdup("%s", ref_target); | ||||||
| 	unsigned char old_sha1[20], new_sha1[20]; | 	unsigned char old_sha1[20], new_sha1[20]; | ||||||
|  |  | ||||||
| 	if (logmsg && read_ref(ref_target, old_sha1)) | 	if (logmsg && read_ref(ref_target, old_sha1)) | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								rerere.c
								
								
								
								
							
							
						
						
									
										2
									
								
								rerere.c
								
								
								
								
							|  | @ -351,7 +351,7 @@ int setup_rerere(struct string_list *merge_rr) | ||||||
| 	if (!is_rerere_enabled()) | 	if (!is_rerere_enabled()) | ||||||
| 		return -1; | 		return -1; | ||||||
|  |  | ||||||
| 	merge_rr_path = xstrdup(git_path("MERGE_RR")); | 	merge_rr_path = git_pathdup("MERGE_RR"); | ||||||
| 	fd = hold_lock_file_for_update(&write_lock, merge_rr_path, | 	fd = hold_lock_file_for_update(&write_lock, merge_rr_path, | ||||||
| 				       LOCK_DIE_ON_ERROR); | 				       LOCK_DIE_ON_ERROR); | ||||||
| 	read_rr(merge_rr); | 	read_rr(merge_rr); | ||||||
|  |  | ||||||
|  | @ -25,7 +25,7 @@ static int add_info_ref(const char *path, const unsigned char *sha1, int flag, v | ||||||
|  |  | ||||||
| static int update_info_refs(int force) | static int update_info_refs(int force) | ||||||
| { | { | ||||||
| 	char *path0 = xstrdup(git_path("info/refs")); | 	char *path0 = git_pathdup("info/refs"); | ||||||
| 	int len = strlen(path0); | 	int len = strlen(path0); | ||||||
| 	char *path1 = xmalloc(len + 2); | 	char *path1 = xmalloc(len + 2); | ||||||
|  |  | ||||||
|  |  | ||||||
|  | @ -245,11 +245,13 @@ int dwim_ref(const char *str, int len, unsigned char *sha1, char **ref) | ||||||
|  |  | ||||||
| 	*ref = NULL; | 	*ref = NULL; | ||||||
| 	for (p = ref_rev_parse_rules; *p; p++) { | 	for (p = ref_rev_parse_rules; *p; p++) { | ||||||
|  | 		char fullref[PATH_MAX]; | ||||||
| 		unsigned char sha1_from_ref[20]; | 		unsigned char sha1_from_ref[20]; | ||||||
| 		unsigned char *this_result; | 		unsigned char *this_result; | ||||||
|  |  | ||||||
| 		this_result = refs_found ? sha1_from_ref : sha1; | 		this_result = refs_found ? sha1_from_ref : sha1; | ||||||
| 		r = resolve_ref(mkpath(*p, len, str), this_result, 1, NULL); | 		mksnpath(fullref, sizeof(fullref), *p, len, str); | ||||||
|  | 		r = resolve_ref(fullref, this_result, 1, NULL); | ||||||
| 		if (r) { | 		if (r) { | ||||||
| 			if (!refs_found++) | 			if (!refs_found++) | ||||||
| 				*ref = xstrdup(r); | 				*ref = xstrdup(r); | ||||||
|  | @ -272,7 +274,7 @@ int dwim_log(const char *str, int len, unsigned char *sha1, char **log) | ||||||
| 		char path[PATH_MAX]; | 		char path[PATH_MAX]; | ||||||
| 		const char *ref, *it; | 		const char *ref, *it; | ||||||
|  |  | ||||||
| 		strcpy(path, mkpath(*p, len, str)); | 		mksnpath(path, sizeof(path), *p, len, str); | ||||||
| 		ref = resolve_ref(path, hash, 1, NULL); | 		ref = resolve_ref(path, hash, 1, NULL); | ||||||
| 		if (!ref) | 		if (!ref) | ||||||
| 			continue; | 			continue; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 Junio C Hamano
						Junio C Hamano