replace unchecked snprintf calls with heap buffers
We'd prefer to avoid unchecked snprintf calls because truncation can lead to unexpected results. These are all cases where truncation shouldn't ever happen, because the input to snprintf is fixed in size. That makes them candidates for xsnprintf(), but it's simpler still to just use the heap, and then nobody has to wonder if "100" is big enough. We'll use xstrfmt() where possible, and a strbuf when we need the resulting size or to reuse the same buffer in a loop. Signed-off-by: Jeff King <peff@peff.net>
Jeff King committed
Mar 28, 2017 at 15:46 UTC
5b1ef2cef4ff9d3213ec81465b99affb4a7c8083
4 files changed
+17
-14
bisect.c
+5
-3
@@ -200,6 +200,7 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
200
{
201
struct commit_list *p;
202
struct commit_dist *array = xcalloc(nr, sizeof(*array));
203
+ struct strbuf buf = STRBUF_INIT;
204
int cnt, i;
205
206
for (p = list, cnt = 0; p; p = p->next) {
@@ -217,17 +218,18 @@ static struct commit_list *best_bisection_sorted(struct commit_list *list, int n
218
}
219
QSORT(array, cnt, compare_commit_dist);
220
for (p = list, i = 0; i < cnt; i++) {
220
- char buf[100]; /* enough for dist=%d */
221
struct object *obj = &(array[i].commit->object);
222
223
- snprintf(buf, sizeof(buf), "dist=%d", array[i].distance);
224
- add_name_decoration(DECORATION_NONE, buf, obj);
223
+ strbuf_reset(&buf);
224
+ strbuf_addf(&buf, "dist=%d", array[i].distance);
225
+ add_name_decoration(DECORATION_NONE, buf.buf, obj);
226
227
p->item = array[i].commit;
228
p = p->next;
229
}
230
if (p)
231
p->next = NULL;
232
+ strbuf_release(&buf);
233
free(array);
234
return list;
235
}
builtin/index-pack.c
+5
-4
@@ -1443,10 +1443,11 @@ static void final(const char *final_pack_name, const char *curr_pack_name,
1443
if (!from_stdin) {
1444
printf("%s\n", sha1_to_hex(sha1));
1445
} else {
1446
- char buf[48];
1447
- int len = snprintf(buf, sizeof(buf), "%s\t%s\n",
1448
- report, sha1_to_hex(sha1));
1449
- write_or_die(1, buf, len);
1446
+ struct strbuf buf = STRBUF_INIT;
1447
+
1448
+ strbuf_addf(&buf, "%s\t%s\n", report, sha1_to_hex(sha1));
1449
+ write_or_die(1, buf.buf, buf.len);
1450
+ strbuf_release(&buf);
1451
1452
/*
1453
* Let's just mimic git-unpack-objects here and write
builtin/notes.c
+4
-5
@@ -554,7 +554,7 @@ static int append_edit(int argc, const char **argv, const char *prefix)
554
struct notes_tree *t;
555
unsigned char object[20], new_note[20];
556
const unsigned char *note;
557
- char logmsg[100];
557
+ char *logmsg;
558
const char * const *usage;
559
struct note_data d = { 0, 0, NULL, STRBUF_INIT };
560
struct option options[] = {
@@ -618,17 +618,16 @@ static int append_edit(int argc, const char **argv, const char *prefix)
618
write_note_data(&d, new_note);
619
if (add_note(t, object, new_note, combine_notes_overwrite))
620
die("BUG: combine_notes_overwrite failed");
621
- snprintf(logmsg, sizeof(logmsg), "Notes added by 'git notes %s'",
622
- argv[0]);
621
+ logmsg = xstrfmt("Notes added by 'git notes %s'", argv[0]);
622
} else {
623
fprintf(stderr, _("Removing note for object %s\n"),
624
sha1_to_hex(object));
625
remove_note(t, object);
627
- snprintf(logmsg, sizeof(logmsg), "Notes removed by 'git notes %s'",
628
- argv[0]);
626
+ logmsg = xstrfmt("Notes removed by 'git notes %s'", argv[0]);
627
}
628
commit_notes(t, logmsg);
629
630
+ free(logmsg);
631
free_note_data(&d);
632
free_notes(t);
633
return 0;
builtin/rev-parse.c
+3
-2
@@ -213,13 +213,14 @@ static int show_abbrev(const unsigned char *sha1, void *cb_data)
213
214
static void show_datestring(const char *flag, const char *datestr)
215
{
216
- static char buffer[100];
216
+ char *buffer;
217
218
/* date handling requires both flags and revs */
219
if ((filter & (DO_FLAGS | DO_REVS)) != (DO_FLAGS | DO_REVS))
220
return;
221
- snprintf(buffer, sizeof(buffer), "%s%lu", flag, approxidate(datestr));
221
+ buffer = xstrfmt("%s%lu", flag, approxidate(datestr));
222
show(buffer);
223
+ free(buffer);
224
}
225
226
static int show_file(const char *arg, int output_prefix)