Skip to content

Commit 6e40947

Browse files
committed
Merge branch 'jk/strip-suffix'
* jk/strip-suffix: prepare_packed_git_one: refactor duplicate-pack check verify-pack: use strbuf_strip_suffix strbuf: implement strbuf_strip_suffix index-pack: use strip_suffix to avoid magic numbers use strip_suffix instead of ends_with in simple cases replace has_extension with ends_with implement ends_with via strip_suffix add strip_suffix function sha1_file: replace PATH_MAX buffer with strbuf in prepare_packed_git_one()
2 parents d518cc0 + 47bf4b0 commit 6e40947

File tree

11 files changed

+101
-84
lines changed

11 files changed

+101
-84
lines changed

builtin/index-pack.c

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1506,7 +1506,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
15061506
const char *curr_index;
15071507
const char *index_name = NULL, *pack_name = NULL;
15081508
const char *keep_name = NULL, *keep_msg = NULL;
1509-
char *index_name_buf = NULL, *keep_name_buf = NULL;
1509+
struct strbuf index_name_buf = STRBUF_INIT,
1510+
keep_name_buf = STRBUF_INIT;
15101511
struct pack_idx_entry **idx_objects;
15111512
struct pack_idx_option opts;
15121513
unsigned char pack_sha1[20];
@@ -1603,24 +1604,22 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
16031604
if (fix_thin_pack && !from_stdin)
16041605
die(_("--fix-thin cannot be used without --stdin"));
16051606
if (!index_name && pack_name) {
1606-
int len = strlen(pack_name);
1607-
if (!has_extension(pack_name, ".pack"))
1607+
size_t len;
1608+
if (!strip_suffix(pack_name, ".pack", &len))
16081609
die(_("packfile name '%s' does not end with '.pack'"),
16091610
pack_name);
1610-
index_name_buf = xmalloc(len);
1611-
memcpy(index_name_buf, pack_name, len - 5);
1612-
strcpy(index_name_buf + len - 5, ".idx");
1613-
index_name = index_name_buf;
1611+
strbuf_add(&index_name_buf, pack_name, len);
1612+
strbuf_addstr(&index_name_buf, ".idx");
1613+
index_name = index_name_buf.buf;
16141614
}
16151615
if (keep_msg && !keep_name && pack_name) {
1616-
int len = strlen(pack_name);
1617-
if (!has_extension(pack_name, ".pack"))
1616+
size_t len;
1617+
if (!strip_suffix(pack_name, ".pack", &len))
16181618
die(_("packfile name '%s' does not end with '.pack'"),
16191619
pack_name);
1620-
keep_name_buf = xmalloc(len);
1621-
memcpy(keep_name_buf, pack_name, len - 5);
1622-
strcpy(keep_name_buf + len - 5, ".keep");
1623-
keep_name = keep_name_buf;
1620+
strbuf_add(&keep_name_buf, pack_name, len);
1621+
strbuf_addstr(&keep_name_buf, ".idx");
1622+
keep_name = keep_name_buf.buf;
16241623
}
16251624
if (verify) {
16261625
if (!index_name)
@@ -1668,8 +1667,8 @@ int cmd_index_pack(int argc, const char **argv, const char *prefix)
16681667
else
16691668
close(input_fd);
16701669
free(objects);
1671-
free(index_name_buf);
1672-
free(keep_name_buf);
1670+
strbuf_release(&index_name_buf);
1671+
strbuf_release(&keep_name_buf);
16731672
if (pack_name == NULL)
16741673
free((void *) curr_pack);
16751674
if (index_name == NULL)

builtin/remote.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -263,16 +263,17 @@ static int config_read_branches(const char *key, const char *value, void *cb)
263263
struct string_list_item *item;
264264
struct branch_info *info;
265265
enum { REMOTE, MERGE, REBASE } type;
266+
size_t key_len;
266267

267268
key += 7;
268-
if (ends_with(key, ".remote")) {
269-
name = xstrndup(key, strlen(key) - 7);
269+
if (strip_suffix(key, ".remote", &key_len)) {
270+
name = xmemdupz(key, key_len);
270271
type = REMOTE;
271-
} else if (ends_with(key, ".merge")) {
272-
name = xstrndup(key, strlen(key) - 6);
272+
} else if (strip_suffix(key, ".merge", &key_len)) {
273+
name = xmemdupz(key, key_len);
273274
type = MERGE;
274-
} else if (ends_with(key, ".rebase")) {
275-
name = xstrndup(key, strlen(key) - 7);
275+
} else if (strip_suffix(key, ".rebase", &key_len)) {
276+
name = xmemdupz(key, key_len);
276277
type = REBASE;
277278
} else
278279
return 0;

builtin/repack.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,16 +83,15 @@ static void get_non_kept_pack_filenames(struct string_list *fname_list)
8383
DIR *dir;
8484
struct dirent *e;
8585
char *fname;
86-
size_t len;
8786

8887
if (!(dir = opendir(packdir)))
8988
return;
9089

9190
while ((e = readdir(dir)) != NULL) {
92-
if (!ends_with(e->d_name, ".pack"))
91+
size_t len;
92+
if (!strip_suffix(e->d_name, ".pack", &len))
9393
continue;
9494

95-
len = strlen(e->d_name) - strlen(".pack");
9695
fname = xmemdupz(e->d_name, len);
9796

9897
if (!file_exists(mkpath("%s/%s.keep", packdir, fname)))

builtin/verify-pack.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -27,10 +27,9 @@ static int verify_one_pack(const char *path, unsigned int flags)
2727
* normalize these forms to "foo.pack" for "index-pack --verify".
2828
*/
2929
strbuf_addstr(&arg, path);
30-
if (has_extension(arg.buf, ".idx"))
31-
strbuf_splice(&arg, arg.len - 3, 3, "pack", 4);
32-
else if (!has_extension(arg.buf, ".pack"))
33-
strbuf_add(&arg, ".pack", 5);
30+
if (strbuf_strip_suffix(&arg, ".idx") ||
31+
!ends_with(arg.buf, ".pack"))
32+
strbuf_addstr(&arg, ".pack");
3433
argv[2] = arg.buf;
3534

3635
memset(&index_pack, 0, sizeof(index_pack));

connected.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,17 @@ static int check_everything_connected_real(sha1_iterate_fn fn,
3131
unsigned char sha1[20];
3232
int err = 0, ac = 0;
3333
struct packed_git *new_pack = NULL;
34+
size_t base_len;
3435

3536
if (fn(cb_data, sha1))
3637
return err;
3738

3839
if (transport && transport->smart_options &&
3940
transport->smart_options->self_contained_and_connected &&
4041
transport->pack_lockfile &&
41-
ends_with(transport->pack_lockfile, ".keep")) {
42+
strip_suffix(transport->pack_lockfile, ".keep", &base_len)) {
4243
struct strbuf idx_file = STRBUF_INIT;
43-
strbuf_addstr(&idx_file, transport->pack_lockfile);
44-
strbuf_setlen(&idx_file, idx_file.len - 5); /* ".keep" */
44+
strbuf_add(&idx_file, transport->pack_lockfile, base_len);
4545
strbuf_addstr(&idx_file, ".idx");
4646
new_pack = add_packed_git(idx_file.buf, idx_file.len, 1);
4747
strbuf_release(&idx_file);

git-compat-util.h

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -347,7 +347,6 @@ extern void set_error_routine(void (*routine)(const char *err, va_list params));
347347
extern void set_die_is_recursing_routine(int (*routine)(void));
348348

349349
extern int starts_with(const char *str, const char *prefix);
350-
extern int ends_with(const char *str, const char *suffix);
351350

352351
/*
353352
* 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,
377376
return 0;
378377
}
379378

379+
/*
380+
* If buf ends with suffix, return 1 and subtract the length of the suffix
381+
* from *len. Otherwise, return 0 and leave *len untouched.
382+
*/
383+
static inline int strip_suffix_mem(const char *buf, size_t *len,
384+
const char *suffix)
385+
{
386+
size_t suflen = strlen(suffix);
387+
if (*len < suflen || memcmp(buf + (*len - suflen), suffix, suflen))
388+
return 0;
389+
*len -= suflen;
390+
return 1;
391+
}
392+
393+
/*
394+
* If str ends with suffix, return 1 and set *len to the size of the string
395+
* without the suffix. Otherwise, return 0 and set *len to the size of the
396+
* string.
397+
*
398+
* Note that we do _not_ NUL-terminate str to the new length.
399+
*/
400+
static inline int strip_suffix(const char *str, const char *suffix, size_t *len)
401+
{
402+
*len = strlen(str);
403+
return strip_suffix_mem(str, len, suffix);
404+
}
405+
406+
static inline int ends_with(const char *str, const char *suffix)
407+
{
408+
size_t len;
409+
return strip_suffix(str, suffix, &len);
410+
}
411+
380412
#if defined(NO_MMAP) || defined(USE_WIN32_MMAP)
381413

382414
#ifndef PROT_READ
@@ -581,13 +613,6 @@ static inline size_t xsize_t(off_t len)
581613
return (size_t)len;
582614
}
583615

584-
static inline int has_extension(const char *filename, const char *ext)
585-
{
586-
size_t len = strlen(filename);
587-
size_t extlen = strlen(ext);
588-
return len > extlen && !memcmp(filename + len - extlen, ext, extlen);
589-
}
590-
591616
/* in ctype.c, for kwset users */
592617
extern const char tolower_trans_tbl[256];
593618

help.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,
144144

145145
while ((de = readdir(dir)) != NULL) {
146146
const char *ent;
147-
int entlen;
147+
size_t entlen;
148148

149149
if (!skip_prefix(de->d_name, prefix, &ent))
150150
continue;
@@ -155,8 +155,7 @@ static void list_commands_in_dir(struct cmdnames *cmds,
155155
continue;
156156

157157
entlen = strlen(ent);
158-
if (has_extension(ent, ".exe"))
159-
entlen -= 4;
158+
strip_suffix(ent, ".exe", &entlen);
160159

161160
add_cmdname(cmds, ent, entlen);
162161
}

refs.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ static void read_loose_refs(const char *dirname, struct ref_dir *dir)
13611361

13621362
if (de->d_name[0] == '.')
13631363
continue;
1364-
if (has_extension(de->d_name, ".lock"))
1364+
if (ends_with(de->d_name, ".lock"))
13651365
continue;
13661366
strbuf_addstr(&refname, de->d_name);
13671367
refdir = *refs->name
@@ -3432,7 +3432,7 @@ static int do_for_each_reflog(struct strbuf *name, each_ref_fn fn, void *cb_data
34323432

34333433
if (de->d_name[0] == '.')
34343434
continue;
3435-
if (has_extension(de->d_name, ".lock"))
3435+
if (ends_with(de->d_name, ".lock"))
34363436
continue;
34373437
strbuf_addstr(name, de->d_name);
34383438
if (stat(git_path("logs/%s", name->buf), &st) < 0) {

sha1_file.c

Lines changed: 26 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,73 +1178,68 @@ static void report_pack_garbage(struct string_list *list)
11781178

11791179
static void prepare_packed_git_one(char *objdir, int local)
11801180
{
1181-
/* Ensure that this buffer is large enough so that we can
1182-
append "/pack/" without clobbering the stack even if
1183-
strlen(objdir) were PATH_MAX. */
1184-
char path[PATH_MAX + 1 + 4 + 1 + 1];
1185-
int len;
1181+
struct strbuf path = STRBUF_INIT;
1182+
size_t dirnamelen;
11861183
DIR *dir;
11871184
struct dirent *de;
11881185
struct string_list garbage = STRING_LIST_INIT_DUP;
11891186

1190-
sprintf(path, "%s/pack", objdir);
1191-
len = strlen(path);
1192-
dir = opendir(path);
1187+
strbuf_addstr(&path, objdir);
1188+
strbuf_addstr(&path, "/pack");
1189+
dir = opendir(path.buf);
11931190
if (!dir) {
11941191
if (errno != ENOENT)
11951192
error("unable to open object pack directory: %s: %s",
1196-
path, strerror(errno));
1193+
path.buf, strerror(errno));
1194+
strbuf_release(&path);
11971195
return;
11981196
}
1199-
path[len++] = '/';
1197+
strbuf_addch(&path, '/');
1198+
dirnamelen = path.len;
12001199
while ((de = readdir(dir)) != NULL) {
1201-
int namelen = strlen(de->d_name);
12021200
struct packed_git *p;
1203-
1204-
if (len + namelen + 1 > sizeof(path)) {
1205-
if (report_garbage) {
1206-
struct strbuf sb = STRBUF_INIT;
1207-
strbuf_addf(&sb, "%.*s/%s", len - 1, path, de->d_name);
1208-
report_garbage("path too long", sb.buf);
1209-
strbuf_release(&sb);
1210-
}
1211-
continue;
1212-
}
1201+
size_t base_len;
12131202

12141203
if (is_dot_or_dotdot(de->d_name))
12151204
continue;
12161205

1217-
strcpy(path + len, de->d_name);
1206+
strbuf_setlen(&path, dirnamelen);
1207+
strbuf_addstr(&path, de->d_name);
12181208

1219-
if (has_extension(de->d_name, ".idx")) {
1209+
base_len = path.len;
1210+
if (strip_suffix_mem(path.buf, &base_len, ".idx")) {
12201211
/* Don't reopen a pack we already have. */
12211212
for (p = packed_git; p; p = p->next) {
1222-
if (!memcmp(path, p->pack_name, len + namelen - 4))
1213+
size_t len;
1214+
if (strip_suffix(p->pack_name, ".pack", &len) &&
1215+
len == base_len &&
1216+
!memcmp(p->pack_name, path.buf, len))
12231217
break;
12241218
}
12251219
if (p == NULL &&
12261220
/*
12271221
* See if it really is a valid .idx file with
12281222
* corresponding .pack file that we can map.
12291223
*/
1230-
(p = add_packed_git(path, len + namelen, local)) != NULL)
1224+
(p = add_packed_git(path.buf, path.len, local)) != NULL)
12311225
install_packed_git(p);
12321226
}
12331227

12341228
if (!report_garbage)
12351229
continue;
12361230

1237-
if (has_extension(de->d_name, ".idx") ||
1238-
has_extension(de->d_name, ".pack") ||
1239-
has_extension(de->d_name, ".bitmap") ||
1240-
has_extension(de->d_name, ".keep"))
1241-
string_list_append(&garbage, path);
1231+
if (ends_with(de->d_name, ".idx") ||
1232+
ends_with(de->d_name, ".pack") ||
1233+
ends_with(de->d_name, ".bitmap") ||
1234+
ends_with(de->d_name, ".keep"))
1235+
string_list_append(&garbage, path.buf);
12421236
else
1243-
report_garbage("garbage found", path);
1237+
report_garbage("garbage found", path.buf);
12441238
}
12451239
closedir(dir);
12461240
report_pack_garbage(&garbage);
12471241
string_list_clear(&garbage, 0);
1242+
strbuf_release(&path);
12481243
}
12491244

12501245
static int sort_pack(const void *a_, const void *b_)

strbuf.c

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,6 @@ int starts_with(const char *str, const char *prefix)
1111
return 0;
1212
}
1313

14-
int ends_with(const char *str, const char *suffix)
15-
{
16-
int len = strlen(str), suflen = strlen(suffix);
17-
if (len < suflen)
18-
return 0;
19-
else
20-
return !strcmp(str + len - suflen, suffix);
21-
}
22-
2314
/*
2415
* Used as the default ->buf value, so that people can always assume
2516
* buf is non NULL and ->buf is NUL terminated even for a freshly

0 commit comments

Comments
 (0)