Skip to content

Commit 7889179

Browse files
committed
Merge branch 'jk/war-on-sprintf'
Many allocations that is manually counted (correctly) that are followed by strcpy/sprintf have been replaced with a less error prone constructs such as xstrfmt. Macintosh-specific breakage was noticed and corrected in this reroll. * jk/war-on-sprintf: (70 commits) name-rev: use strip_suffix to avoid magic numbers use strbuf_complete to conditionally append slash fsck: use for_each_loose_file_in_objdir Makefile: drop D_INO_IN_DIRENT build knob fsck: drop inode-sorting code convert strncpy to memcpy notes: document length of fanout path with a constant color: add color_set helper for copying raw colors prefer memcpy to strcpy help: clean up kfmclient munging receive-pack: simplify keep_arg computation avoid sprintf and strcpy with flex arrays use alloc_ref rather than hand-allocating "struct ref" color: add overflow checks for parsing colors drop strcpy in favor of raw sha1_to_hex use sha1_to_hex_r() instead of strcpy daemon: use cld->env_array when re-spawning stat_tracking_info: convert to argv_array http-push: use an argv_array for setup_revisions fetch-pack: use argv_array for index-pack / unpack-objects ...
2 parents 614a2ac + 34e02de commit 7889179

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+946
-1056
lines changed

Makefile

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,6 @@ all::
7474
# Define HAVE_PATHS_H if you have paths.h and want to use the default PATH
7575
# it specifies.
7676
#
77-
# Define NO_D_INO_IN_DIRENT if you don't have d_ino in your struct dirent.
78-
#
7977
# Define NO_D_TYPE_IN_DIRENT if your platform defines DT_UNKNOWN but lacks
8078
# d_type in struct dirent (Cygwin 1.5, fixed in Cygwin 1.7).
8179
#
@@ -1164,9 +1162,6 @@ endif
11641162
ifdef NO_D_TYPE_IN_DIRENT
11651163
BASIC_CFLAGS += -DNO_D_TYPE_IN_DIRENT
11661164
endif
1167-
ifdef NO_D_INO_IN_DIRENT
1168-
BASIC_CFLAGS += -DNO_D_INO_IN_DIRENT
1169-
endif
11701165
ifdef NO_GECOS_IN_PWENT
11711166
BASIC_CFLAGS += -DNO_GECOS_IN_PWENT
11721167
endif

archive-tar.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -167,21 +167,21 @@ static void prepare_header(struct archiver_args *args,
167167
struct ustar_header *header,
168168
unsigned int mode, unsigned long size)
169169
{
170-
sprintf(header->mode, "%07o", mode & 07777);
171-
sprintf(header->size, "%011lo", S_ISREG(mode) ? size : 0);
172-
sprintf(header->mtime, "%011lo", (unsigned long) args->time);
170+
xsnprintf(header->mode, sizeof(header->mode), "%07o", mode & 07777);
171+
xsnprintf(header->size, sizeof(header->size), "%011lo", S_ISREG(mode) ? size : 0);
172+
xsnprintf(header->mtime, sizeof(header->mtime), "%011lo", (unsigned long) args->time);
173173

174-
sprintf(header->uid, "%07o", 0);
175-
sprintf(header->gid, "%07o", 0);
174+
xsnprintf(header->uid, sizeof(header->uid), "%07o", 0);
175+
xsnprintf(header->gid, sizeof(header->gid), "%07o", 0);
176176
strlcpy(header->uname, "root", sizeof(header->uname));
177177
strlcpy(header->gname, "root", sizeof(header->gname));
178-
sprintf(header->devmajor, "%07o", 0);
179-
sprintf(header->devminor, "%07o", 0);
178+
xsnprintf(header->devmajor, sizeof(header->devmajor), "%07o", 0);
179+
xsnprintf(header->devminor, sizeof(header->devminor), "%07o", 0);
180180

181181
memcpy(header->magic, "ustar", 6);
182182
memcpy(header->version, "00", 2);
183183

184-
sprintf(header->chksum, "%07o", ustar_header_chksum(header));
184+
snprintf(header->chksum, sizeof(header->chksum), "%07o", ustar_header_chksum(header));
185185
}
186186

187187
static int write_extended_header(struct archiver_args *args,
@@ -193,7 +193,7 @@ static int write_extended_header(struct archiver_args *args,
193193
memset(&header, 0, sizeof(header));
194194
*header.typeflag = TYPEFLAG_EXT_HEADER;
195195
mode = 0100666;
196-
sprintf(header.name, "%s.paxheader", sha1_to_hex(sha1));
196+
xsnprintf(header.name, sizeof(header.name), "%s.paxheader", sha1_to_hex(sha1));
197197
prepare_header(args, &header, mode, size);
198198
write_blocked(&header, sizeof(header));
199199
write_blocked(buffer, size);
@@ -233,10 +233,10 @@ static int write_tar_entry(struct archiver_args *args,
233233
size_t rest = pathlen - plen - 1;
234234
if (plen > 0 && rest <= sizeof(header.name)) {
235235
memcpy(header.prefix, path, plen);
236-
memcpy(header.name, path + plen + 1, rest);
236+
memcpy(header.name, path + plen + 1, rest);
237237
} else {
238-
sprintf(header.name, "%s.data",
239-
sha1_to_hex(sha1));
238+
xsnprintf(header.name, sizeof(header.name), "%s.data",
239+
sha1_to_hex(sha1));
240240
strbuf_append_ext_header(&ext_header, "path",
241241
path, pathlen);
242242
}
@@ -259,8 +259,8 @@ static int write_tar_entry(struct archiver_args *args,
259259

260260
if (S_ISLNK(mode)) {
261261
if (size > sizeof(header.linkname)) {
262-
sprintf(header.linkname, "see %s.paxheader",
263-
sha1_to_hex(sha1));
262+
xsnprintf(header.linkname, sizeof(header.linkname),
263+
"see %s.paxheader", sha1_to_hex(sha1));
264264
strbuf_append_ext_header(&ext_header, "linkpath",
265265
buffer, size);
266266
} else
@@ -301,7 +301,7 @@ static int write_global_extended_header(struct archiver_args *args)
301301
memset(&header, 0, sizeof(header));
302302
*header.typeflag = TYPEFLAG_GLOBAL_HEADER;
303303
mode = 0100666;
304-
strcpy(header.name, "pax_global_header");
304+
xsnprintf(header.name, sizeof(header.name), "pax_global_header");
305305
prepare_header(args, &header, mode, ext_header.len);
306306
write_blocked(&header, sizeof(header));
307307
write_blocked(ext_header.buf, ext_header.len);

archive.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,13 +171,14 @@ static void queue_directory(const unsigned char *sha1,
171171
unsigned mode, int stage, struct archiver_context *c)
172172
{
173173
struct directory *d;
174-
d = xmallocz(sizeof(*d) + base->len + 1 + strlen(filename));
174+
size_t len = base->len + 1 + strlen(filename) + 1;
175+
d = xmalloc(sizeof(*d) + len);
175176
d->up = c->bottom;
176177
d->baselen = base->len;
177178
d->mode = mode;
178179
d->stage = stage;
179180
c->bottom = d;
180-
d->len = sprintf(d->path, "%.*s%s/", (int)base->len, base->buf, filename);
181+
d->len = xsnprintf(d->path, len, "%.*s%s/", (int)base->len, base->buf, filename);
181182
hashcpy(d->oid.hash, sha1);
182183
}
183184

builtin/apply.c

Lines changed: 10 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,7 @@ static enum ws_ignore {
7777

7878

7979
static const char *patch_input_file;
80-
static const char *root;
81-
static int root_len;
80+
static struct strbuf root = STRBUF_INIT;
8281
static int read_stdin = 1;
8382
static int options;
8483

@@ -494,8 +493,8 @@ static char *find_name_gnu(const char *line, const char *def, int p_value)
494493
}
495494

496495
strbuf_remove(&name, 0, cp - name.buf);
497-
if (root)
498-
strbuf_insert(&name, 0, root, root_len);
496+
if (root.len)
497+
strbuf_insert(&name, 0, root.buf, root.len);
499498
return squash_slash(strbuf_detach(&name, NULL));
500499
}
501500

@@ -697,11 +696,8 @@ static char *find_name_common(const char *line, const char *def,
697696
return squash_slash(xstrdup(def));
698697
}
699698

700-
if (root) {
701-
char *ret = xmalloc(root_len + len + 1);
702-
strcpy(ret, root);
703-
memcpy(ret + root_len, start, len);
704-
ret[root_len + len] = '\0';
699+
if (root.len) {
700+
char *ret = xstrfmt("%s%.*s", root.buf, len, start);
705701
return squash_slash(ret);
706702
}
707703

@@ -1277,8 +1273,8 @@ static int parse_git_header(const char *line, int len, unsigned int size, struct
12771273
* the default name from the header.
12781274
*/
12791275
patch->def_name = git_header_name(line, len);
1280-
if (patch->def_name && root) {
1281-
char *s = xstrfmt("%s%s", root, patch->def_name);
1276+
if (patch->def_name && root.len) {
1277+
char *s = xstrfmt("%s%s", root.buf, patch->def_name);
12821278
free(patch->def_name);
12831279
patch->def_name = s;
12841280
}
@@ -4501,14 +4497,9 @@ static int option_parse_whitespace(const struct option *opt,
45014497
static int option_parse_directory(const struct option *opt,
45024498
const char *arg, int unset)
45034499
{
4504-
root_len = strlen(arg);
4505-
if (root_len && arg[root_len - 1] != '/') {
4506-
char *new_root;
4507-
root = new_root = xmalloc(root_len + 2);
4508-
strcpy(new_root, arg);
4509-
strcpy(new_root + root_len++, "/");
4510-
} else
4511-
root = arg;
4500+
strbuf_reset(&root);
4501+
strbuf_addstr(&root, arg);
4502+
strbuf_complete(&root, '/');
45124503
return 0;
45134504
}
45144505

builtin/blame.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,13 @@ static void queue_blames(struct scoreboard *sb, struct origin *porigin,
459459
static struct origin *make_origin(struct commit *commit, const char *path)
460460
{
461461
struct origin *o;
462-
o = xcalloc(1, sizeof(*o) + strlen(path) + 1);
462+
size_t pathlen = strlen(path) + 1;
463+
o = xcalloc(1, sizeof(*o) + pathlen);
463464
o->commit = commit;
464465
o->refcnt = 1;
465466
o->next = commit->util;
466467
commit->util = o;
467-
strcpy(o->path, path);
468+
memcpy(o->path, path, pathlen); /* includes NUL */
468469
return o;
469470
}
470471

@@ -1879,9 +1880,9 @@ static void emit_porcelain(struct scoreboard *sb, struct blame_entry *ent,
18791880
int cnt;
18801881
const char *cp;
18811882
struct origin *suspect = ent->suspect;
1882-
char hex[41];
1883+
char hex[GIT_SHA1_HEXSZ + 1];
18831884

1884-
strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));
1885+
sha1_to_hex_r(hex, suspect->commit->object.sha1);
18851886
printf("%s %d %d %d\n",
18861887
hex,
18871888
ent->s_lno + 1,
@@ -1917,11 +1918,11 @@ static void emit_other(struct scoreboard *sb, struct blame_entry *ent, int opt)
19171918
const char *cp;
19181919
struct origin *suspect = ent->suspect;
19191920
struct commit_info ci;
1920-
char hex[41];
1921+
char hex[GIT_SHA1_HEXSZ + 1];
19211922
int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP);
19221923

19231924
get_commit_info(suspect->commit, &ci, 1);
1924-
strcpy(hex, sha1_to_hex(suspect->commit->object.sha1));
1925+
sha1_to_hex_r(hex, suspect->commit->object.sha1);
19251926

19261927
cp = nth_line(sb, ent->lno);
19271928
for (cnt = 0; cnt < ent->num_lines; cnt++) {

builtin/clean.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,7 @@ static int is_git_repository(struct strbuf *path)
159159
int gitfile_error;
160160
size_t orig_path_len = path->len;
161161
assert(orig_path_len != 0);
162-
if (path->buf[orig_path_len - 1] != '/')
163-
strbuf_addch(path, '/');
162+
strbuf_complete(path, '/');
164163
strbuf_addstr(path, ".git");
165164
if (read_gitfile_gently(path->buf, &gitfile_error) || is_git_directory(path->buf))
166165
ret = 1;
@@ -206,8 +205,7 @@ static int remove_dirs(struct strbuf *path, const char *prefix, int force_flag,
206205
return res;
207206
}
208207

209-
if (path->buf[original_len - 1] != '/')
210-
strbuf_addch(path, '/');
208+
strbuf_complete(path, '/');
211209

212210
len = path->len;
213211
while ((e = readdir(dir)) != NULL) {

builtin/config.c

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,6 @@ static int get_value(const char *key_, const char *regex_)
246246

247247
static char *normalize_value(const char *key, const char *value)
248248
{
249-
char *normalized;
250-
251249
if (!value)
252250
return NULL;
253251

@@ -258,27 +256,21 @@ static char *normalize_value(const char *key, const char *value)
258256
* "~/foobar/" in the config file, and to expand the ~
259257
* when retrieving the value.
260258
*/
261-
normalized = xstrdup(value);
262-
else {
263-
normalized = xmalloc(64);
264-
if (types == TYPE_INT) {
265-
int64_t v = git_config_int64(key, value);
266-
sprintf(normalized, "%"PRId64, v);
267-
}
268-
else if (types == TYPE_BOOL)
269-
sprintf(normalized, "%s",
270-
git_config_bool(key, value) ? "true" : "false");
271-
else if (types == TYPE_BOOL_OR_INT) {
272-
int is_bool, v;
273-
v = git_config_bool_or_int(key, value, &is_bool);
274-
if (!is_bool)
275-
sprintf(normalized, "%d", v);
276-
else
277-
sprintf(normalized, "%s", v ? "true" : "false");
278-
}
259+
return xstrdup(value);
260+
if (types == TYPE_INT)
261+
return xstrfmt("%"PRId64, git_config_int64(key, value));
262+
if (types == TYPE_BOOL)
263+
return xstrdup(git_config_bool(key, value) ? "true" : "false");
264+
if (types == TYPE_BOOL_OR_INT) {
265+
int is_bool, v;
266+
v = git_config_bool_or_int(key, value, &is_bool);
267+
if (!is_bool)
268+
return xstrfmt("%d", v);
269+
else
270+
return xstrdup(v ? "true" : "false");
279271
}
280272

281-
return normalized;
273+
die("BUG: cannot normalize type %d", types);
282274
}
283275

284276
static int get_color_found;

builtin/fetch.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -528,36 +528,38 @@ static int update_local_ref(struct ref *ref,
528528
}
529529

530530
if (in_merge_bases(current, updated)) {
531-
char quickref[83];
531+
struct strbuf quickref = STRBUF_INIT;
532532
int r;
533-
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
534-
strcat(quickref, "..");
535-
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
533+
strbuf_add_unique_abbrev(&quickref, current->object.sha1, DEFAULT_ABBREV);
534+
strbuf_addstr(&quickref, "..");
535+
strbuf_add_unique_abbrev(&quickref, ref->new_sha1, DEFAULT_ABBREV);
536536
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
537537
(recurse_submodules != RECURSE_SUBMODULES_ON))
538538
check_for_new_submodule_commits(ref->new_sha1);
539539
r = s_update_ref("fast-forward", ref, 1);
540540
strbuf_addf(display, "%c %-*s %-*s -> %s%s",
541541
r ? '!' : ' ',
542-
TRANSPORT_SUMMARY_WIDTH, quickref,
542+
TRANSPORT_SUMMARY_WIDTH, quickref.buf,
543543
REFCOL_WIDTH, remote, pretty_ref,
544544
r ? _(" (unable to update local ref)") : "");
545+
strbuf_release(&quickref);
545546
return r;
546547
} else if (force || ref->force) {
547-
char quickref[84];
548+
struct strbuf quickref = STRBUF_INIT;
548549
int r;
549-
strcpy(quickref, find_unique_abbrev(current->object.sha1, DEFAULT_ABBREV));
550-
strcat(quickref, "...");
551-
strcat(quickref, find_unique_abbrev(ref->new_sha1, DEFAULT_ABBREV));
550+
strbuf_add_unique_abbrev(&quickref, current->object.sha1, DEFAULT_ABBREV);
551+
strbuf_addstr(&quickref, "...");
552+
strbuf_add_unique_abbrev(&quickref, ref->new_sha1, DEFAULT_ABBREV);
552553
if ((recurse_submodules != RECURSE_SUBMODULES_OFF) &&
553554
(recurse_submodules != RECURSE_SUBMODULES_ON))
554555
check_for_new_submodule_commits(ref->new_sha1);
555556
r = s_update_ref("forced-update", ref, 1);
556557
strbuf_addf(display, "%c %-*s %-*s -> %s (%s)",
557558
r ? '!' : '+',
558-
TRANSPORT_SUMMARY_WIDTH, quickref,
559+
TRANSPORT_SUMMARY_WIDTH, quickref.buf,
559560
REFCOL_WIDTH, remote, pretty_ref,
560561
r ? _("unable to update local ref") : _("forced update"));
562+
strbuf_release(&quickref);
561563
return r;
562564
} else {
563565
strbuf_addf(display, "! %-*s %-*s -> %s %s",
@@ -637,8 +639,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name,
637639
continue;
638640

639641
if (rm->peer_ref) {
640-
ref = xcalloc(1, sizeof(*ref) + strlen(rm->peer_ref->name) + 1);
641-
strcpy(ref->name, rm->peer_ref->name);
642+
ref = alloc_ref(rm->peer_ref->name);
642643
hashcpy(ref->old_sha1, rm->peer_ref->old_sha1);
643644
hashcpy(ref->new_sha1, rm->old_sha1);
644645
ref->force = rm->peer_ref->force;
@@ -1156,11 +1157,8 @@ int cmd_fetch(int argc, const char **argv, const char *prefix)
11561157
die(_("--depth and --unshallow cannot be used together"));
11571158
else if (!is_repository_shallow())
11581159
die(_("--unshallow on a complete repository does not make sense"));
1159-
else {
1160-
static char inf_depth[12];
1161-
sprintf(inf_depth, "%d", INFINITE_DEPTH);
1162-
depth = inf_depth;
1163-
}
1160+
else
1161+
depth = xstrfmt("%d", INFINITE_DEPTH);
11641162
}
11651163

11661164
/* no need to be strict, transport_set_option() will validate it again */

0 commit comments

Comments
 (0)