diff options
| -rw-r--r-- | builtin/index-pack.c | 29 | ||||
| -rw-r--r-- | builtin/remote.c | 13 | ||||
| -rw-r--r-- | builtin/repack.c | 5 | ||||
| -rw-r--r-- | builtin/verify-pack.c | 7 | ||||
| -rw-r--r-- | connected.c | 6 | ||||
| -rw-r--r-- | git-compat-util.h | 41 | ||||
| -rw-r--r-- | help.c | 5 | ||||
| -rw-r--r-- | refs.c | 4 | ||||
| -rw-r--r-- | sha1_file.c | 57 | ||||
| -rw-r--r-- | strbuf.c | 9 | ||||
| -rw-r--r-- | strbuf.h | 9 | 
11 files changed, 101 insertions, 84 deletions
| diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 8b3bd29dbc..fc40411892 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1506,7 +1506,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)  	const char *curr_index;  	const char *index_name = NULL, *pack_name = NULL;  	const char *keep_name = NULL, *keep_msg = NULL; -	char *index_name_buf = NULL, *keep_name_buf = NULL; +	struct strbuf index_name_buf = STRBUF_INIT, +		      keep_name_buf = STRBUF_INIT;  	struct pack_idx_entry **idx_objects;  	struct pack_idx_option opts;  	unsigned char pack_sha1[20]; @@ -1603,24 +1604,22 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)  	if (fix_thin_pack && !from_stdin)  		die(_("--fix-thin cannot be used without --stdin"));  	if (!index_name && pack_name) { -		int len = strlen(pack_name); -		if (!has_extension(pack_name, ".pack")) +		size_t len; +		if (!strip_suffix(pack_name, ".pack", &len))  			die(_("packfile name '%s' does not end with '.pack'"),  			    pack_name); -		index_name_buf = xmalloc(len); -		memcpy(index_name_buf, pack_name, len - 5); -		strcpy(index_name_buf + len - 5, ".idx"); -		index_name = index_name_buf; +		strbuf_add(&index_name_buf, pack_name, len); +		strbuf_addstr(&index_name_buf, ".idx"); +		index_name = index_name_buf.buf;  	}  	if (keep_msg && !keep_name && pack_name) { -		int len = strlen(pack_name); -		if (!has_extension(pack_name, ".pack")) +		size_t len; +		if (!strip_suffix(pack_name, ".pack", &len))  			die(_("packfile name '%s' does not end with '.pack'"),  			    pack_name); -		keep_name_buf = xmalloc(len); -		memcpy(keep_name_buf, pack_name, len - 5); -		strcpy(keep_name_buf + len - 5, ".keep"); -		keep_name = keep_name_buf; +		strbuf_add(&keep_name_buf, pack_name, len); +		strbuf_addstr(&keep_name_buf, ".idx"); +		keep_name = keep_name_buf.buf;  	}  	if (verify) {  		if (!index_name) @@ -1668,8 +1667,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)  	else  		close(input_fd);  	free(objects); -	free(index_name_buf); -	free(keep_name_buf); +	strbuf_release(&index_name_buf); +	strbuf_release(&keep_name_buf);  	if (pack_name == NULL)  		free((void *) curr_pack);  	if (index_name == NULL) diff --git a/builtin/remote.c b/builtin/remote.c index a8efe3da4d..8e1dc39162 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -263,16 +263,17 @@ static int config_read_branches(const char *key, const char *value, void *cb)  		struct string_list_item *item;  		struct branch_info *info;  		enum { REMOTE, MERGE, REBASE } type; +		size_t key_len;  		key += 7; -		if (ends_with(key, ".remote")) { -			name = xstrndup(key, strlen(key) - 7); +		if (strip_suffix(key, ".remote", &key_len)) { +			name = xmemdupz(key, key_len);  			type = REMOTE; -		} else if (ends_with(key, ".merge")) { -			name = xstrndup(key, strlen(key) - 6); +		} else if (strip_suffix(key, ".merge", &key_len)) { +			name = xmemdupz(key, key_len);  			type = MERGE; -		} else if (ends_with(key, ".rebase")) { -			name = xstrndup(key, strlen(key) - 7); +		} else if (strip_suffix(key, ".rebase", &key_len)) { +			name = xmemdupz(key, key_len);  			type = REBASE;  		} else  			return 0; diff --git a/builtin/repack.c b/builtin/repack.c index ff2216a7aa..a77e743b94 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -83,16 +83,15 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list)  	DIR *dir;  	struct dirent *e;  	char *fname; -	size_t len;  	if (!(dir = opendir(packdir)))  		return;  	while ((e = readdir(dir)) != NULL) { -		if (!ends_with(e->d_name, ".pack")) +		size_t len; +		if (!strip_suffix(e->d_name, ".pack", &len))  			continue; -		len = strlen(e->d_name) - strlen(".pack");  		fname = xmemdupz(e->d_name, len);  		if (!file_exists(mkpath("%s/%s.keep", packdir, fname))) diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index 66cd2df0f8..972579f33c 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -27,10 +27,9 @@ static int verify_one_pack(const char *path, unsigned int flags)  	 * normalize these forms to "foo.pack" for "index-pack --verify".  	 */  	strbuf_addstr(&arg, path); -	if (has_extension(arg.buf, ".idx")) -		strbuf_splice(&arg, arg.len - 3, 3, "pack", 4); -	else if (!has_extension(arg.buf, ".pack")) -		strbuf_add(&arg, ".pack", 5); +	if (strbuf_strip_suffix(&arg, ".idx") || +	    !ends_with(arg.buf, ".pack")) +		strbuf_addstr(&arg, ".pack");  	argv[2] = arg.buf;  	memset(&index_pack, 0, sizeof(index_pack)); diff --git a/connected.c b/connected.c index be0253e21b..dae9c9972e 100644 --- a/connected.c +++ b/connected.c @@ -31,6 +31,7 @@ static int check_everything_connected_real(sha1_iterate_fn fn,  	unsigned char sha1[20];  	int err = 0, ac = 0;  	struct packed_git *new_pack = NULL; +	size_t base_len;  	if (fn(cb_data, sha1))  		return err; @@ -38,10 +39,9 @@ static int check_everything_connected_real(sha1_iterate_fn fn,  	if (transport && transport->smart_options &&  	    transport->smart_options->self_contained_and_connected &&  	    transport->pack_lockfile && -	    ends_with(transport->pack_lockfile, ".keep")) { +	    strip_suffix(transport->pack_lockfile, ".keep", &base_len)) {  		struct strbuf idx_file = STRBUF_INIT; -		strbuf_addstr(&idx_file, transport->pack_lockfile); -		strbuf_setlen(&idx_file, idx_file.len - 5); /* ".keep" */ +		strbuf_add(&idx_file, transport->pack_lockfile, base_len);  		strbuf_addstr(&idx_file, ".idx");  		new_pack = add_packed_git(idx_file.buf, idx_file.len, 1);  		strbuf_release(&idx_file); diff --git a/git-compat-util.h b/git-compat-util.h index 9de3180710..0b53c9a4af 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -347,7 +347,6 @@ extern void set_error_routine(void (*routine)(const char *err, va_list params));  extern void set_die_is_recursing_routine(int (*routine)(void));  extern int starts_with(const char *str, const char *prefix); -extern int ends_with(const char *str, const char *suffix);  /*   * If the string "str" begins with the string found in "prefix", return 1. @@ -377,6 +376,39 @@ static inline int skip_prefix(const char *str, const char *prefix,  	return 0;  } +/* + * If buf ends with suffix, return 1 and subtract the length of the suffix + * from *len. Otherwise, return 0 and leave *len untouched. + */ +static inline int strip_suffix_mem(const char *buf, size_t *len, +				   const char *suffix) +{ +	size_t suflen = strlen(suffix); +	if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen)) +		return 0; +	*len -= suflen; +	return 1; +} + +/* + * If str ends with suffix, return 1 and set *len to the size of the string + * without the suffix. Otherwise, return 0 and set *len to the size of the + * string. + * + * Note that we do _not_ NUL-terminate str to the new length. + */ +static inline int strip_suffix(const char *str, const char *suffix, size_t *len) +{ +	*len = strlen(str); +	return strip_suffix_mem(str, len, suffix); +} + +static inline int ends_with(const char *str, const char *suffix) +{ +	size_t len; +	return strip_suffix(str, suffix, &len); +} +  #if defined(NO_MMAP) || defined(USE_WIN32_MMAP)  #ifndef PROT_READ @@ -581,13 +613,6 @@ 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); -	size_t extlen = strlen(ext); -	return len > extlen && !memcmp(filename + len - extlen, ext, extlen); -} -  /* in ctype.c, for kwset users */  extern const char tolower_trans_tbl[256]; @@ -144,7 +144,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,  	while ((de = readdir(dir)) != NULL) {  		const char *ent; -		int entlen; +		size_t entlen;  		if (!skip_prefix(de->d_name, prefix, &ent))  			continue; @@ -155,8 +155,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,  			continue;  		entlen = strlen(ent); -		if (has_extension(ent, ".exe")) -			entlen -= 4; +		strip_suffix(ent, ".exe", &entlen);  		add_cmdname(cmds, ent, entlen);  	} @@ -1361,7 +1361,7 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)  		if (de->d_name[0] == '.')  			continue; -		if (has_extension(de->d_name, ".lock")) +		if (ends_with(de->d_name, ".lock"))  			continue;  		strbuf_addstr(&refname, de->d_name);  		refdir = *refs->name @@ -3432,7 +3432,7 @@ static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data  		if (de->d_name[0] == '.')  			continue; -		if (has_extension(de->d_name, ".lock")) +		if (ends_with(de->d_name, ".lock"))  			continue;  		strbuf_addstr(name, de->d_name);  		if (stat(git_path("logs/%s", name->buf), &st) < 0) { diff --git a/sha1_file.c b/sha1_file.c index a38854ce55..4127ae138d 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -1178,48 +1178,42 @@ static void report_pack_garbage(struct string_list *list)  static void prepare_packed_git_one(char *objdir, int local)  { -	/* Ensure that this buffer is large enough so that we can -	   append "/pack/" without clobbering the stack even if -	   strlen(objdir) were PATH_MAX.  */ -	char path[PATH_MAX + 1 + 4 + 1 + 1]; -	int len; +	struct strbuf path = STRBUF_INIT; +	size_t dirnamelen;  	DIR *dir;  	struct dirent *de;  	struct string_list garbage = STRING_LIST_INIT_DUP; -	sprintf(path, "%s/pack", objdir); -	len = strlen(path); -	dir = opendir(path); +	strbuf_addstr(&path, objdir); +	strbuf_addstr(&path, "/pack"); +	dir = opendir(path.buf);  	if (!dir) {  		if (errno != ENOENT)  			error("unable to open object pack directory: %s: %s", -			      path, strerror(errno)); +			      path.buf, strerror(errno)); +		strbuf_release(&path);  		return;  	} -	path[len++] = '/'; +	strbuf_addch(&path, '/'); +	dirnamelen = path.len;  	while ((de = readdir(dir)) != NULL) { -		int namelen = strlen(de->d_name);  		struct packed_git *p; - -		if (len + namelen + 1 > sizeof(path)) { -			if (report_garbage) { -				struct strbuf sb = STRBUF_INIT; -				strbuf_addf(&sb, "%.*s/%s", len - 1, path, de->d_name); -				report_garbage("path too long", sb.buf); -				strbuf_release(&sb); -			} -			continue; -		} +		size_t base_len;  		if (is_dot_or_dotdot(de->d_name))  			continue; -		strcpy(path + len, de->d_name); +		strbuf_setlen(&path, dirnamelen); +		strbuf_addstr(&path, de->d_name); -		if (has_extension(de->d_name, ".idx")) { +		base_len = path.len; +		if (strip_suffix_mem(path.buf, &base_len, ".idx")) {  			/* Don't reopen a pack we already have. */  			for (p = packed_git; p; p = p->next) { -				if (!memcmp(path, p->pack_name, len + namelen - 4)) +				size_t len; +				if (strip_suffix(p->pack_name, ".pack", &len) && +				    len == base_len && +				    !memcmp(p->pack_name, path.buf, len))  					break;  			}  			if (p == NULL && @@ -1227,24 +1221,25 @@ static void prepare_packed_git_one(char *objdir, int local)  			     * See if it really is a valid .idx file with  			     * corresponding .pack file that we can map.  			     */ -			    (p = add_packed_git(path, len + namelen, local)) != NULL) +			    (p = add_packed_git(path.buf, path.len, local)) != NULL)  				install_packed_git(p);  		}  		if (!report_garbage)  			continue; -		if (has_extension(de->d_name, ".idx") || -		    has_extension(de->d_name, ".pack") || -		    has_extension(de->d_name, ".bitmap") || -		    has_extension(de->d_name, ".keep")) -			string_list_append(&garbage, path); +		if (ends_with(de->d_name, ".idx") || +		    ends_with(de->d_name, ".pack") || +		    ends_with(de->d_name, ".bitmap") || +		    ends_with(de->d_name, ".keep")) +			string_list_append(&garbage, path.buf);  		else -			report_garbage("garbage found", path); +			report_garbage("garbage found", path.buf);  	}  	closedir(dir);  	report_pack_garbage(&garbage);  	string_list_clear(&garbage, 0); +	strbuf_release(&path);  }  static int sort_pack(const void *a_, const void *b_) @@ -11,15 +11,6 @@ int starts_with(const char *str, const char *prefix)  			return 0;  } -int ends_with(const char *str, const char *suffix) -{ -	int len = strlen(str), suflen = strlen(suffix); -	if (len < suflen) -		return 0; -	else -		return !strcmp(str + len - suflen, suffix); -} -  /*   * Used as the default ->buf value, so that people can always assume   * buf is non NULL and ->buf is NUL terminated even for a freshly @@ -49,6 +49,15 @@ extern int strbuf_reencode(struct strbuf *sb, const char *from, const char *to);  extern void strbuf_tolower(struct strbuf *sb);  extern int strbuf_cmp(const struct strbuf *, const struct strbuf *); +static inline int strbuf_strip_suffix(struct strbuf *sb, const char *suffix) +{ +	if (strip_suffix_mem(sb->buf, &sb->len, suffix)) { +		strbuf_setlen(sb, sb->len); +		return 1; +	} else +		return 0; +} +  /*   * Split str (of length slen) at the specified terminator character.   * Return a null-terminated array of pointers to strbuf objects | 
