string-list API: change "nr" and "alloc" to "size_t"

Change the "nr" and "alloc" members of "struct string_list" to use "size_t" instead of "nr". On some platforms the size of an "unsigned int" will be smaller than a "size_t", e.g. a 32 bit unsigned v.s. 64 bit unsigned. As "struct string_list" is a generic API we use in a lot of places this might cause overflows. As one example: code in "refs.c" keeps track of the number of refs with a "size_t", and auxiliary code in builtin/remote.c in get_ref_states() appends those to a "struct string_list". While we're at it split the "nr" and "alloc" in string-list.h across two lines, which is the case for most such struct member declarations (e.g. in "strbuf.h" and "strvec.h"). Changing e.g. "int i" to "size_t i" in run_and_feed_hook() isn't strictly necessary, and there are a lot more cases where we'll use a local "int", "unsigned int" etc. variable derived from the "nr" in the "struct string_list". But in that case as well as add_wrapped_shortlog_msg() in builtin/shortlog.c we need to adjust the printf format referring to "nr" anyway, so let's also change the other variables referring to it. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Ævar Arnfjörð Bjarmason committed Mar 7, 2022 at 16:27 UTC 99d60545f87445d7050999b826fc4cd49e69376c
9 files changed +35 -31
builtin/receive-pack.c
+5 -4
@@ -813,13 +813,14 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed,
813 proc.trace2_hook_name = hook_name;
814
815 if (feed_state->push_options) {
816 - int i;
816 + size_t i;
817 for (i = 0; i < feed_state->push_options->nr; i++)
818 strvec_pushf(&proc.env_array,
819 - "GIT_PUSH_OPTION_%d=%s", i,
819 + "GIT_PUSH_OPTION_%"PRIuMAX"=%s",
820 + (uintmax_t)i,
821 feed_state->push_options->items[i].string);
821 - strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%d",
822 - feed_state->push_options->nr);
822 + strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%"PRIuMAX"",
823 + (uintmax_t)feed_state->push_options->nr);
824 } else
825 strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT");
826
builtin/shortlog.c
+5 -5
@@ -435,7 +435,7 @@ static void add_wrapped_shortlog_msg(struct strbuf *sb, const char *s,
435
436 void shortlog_output(struct shortlog *log)
437 {
438 - int i, j;
438 + size_t i, j;
439 struct strbuf sb = STRBUF_INIT;
440
441 if (log->sort_by_number)
@@ -448,10 +448,10 @@ void shortlog_output(struct shortlog *log)
448 (int)UTIL_TO_INT(item), item->string);
449 } else {
450 struct string_list *onelines = item->util;
451 - fprintf(log->file, "%s (%d):\n",
452 - item->string, onelines->nr);
453 - for (j = onelines->nr - 1; j >= 0; j--) {
454 - const char *msg = onelines->items[j].string;
451 + fprintf(log->file, "%s (%"PRIuMAX"):\n",
452 + item->string, (uintmax_t)onelines->nr);
453 + for (j = onelines->nr; j >= 1; j--) {
454 + const char *msg = onelines->items[j - 1].string;
455
456 if (log->wrap_lines) {
457 strbuf_reset(&sb);
bundle.c
+4 -4
@@ -255,18 +255,18 @@ int verify_bundle(struct repository *r,
255
256 r = &header->references;
257 printf_ln(Q_("The bundle contains this ref:",
258 - "The bundle contains these %d refs:",
258 + "The bundle contains these %"PRIuMAX" refs:",
259 r->nr),
260 - r->nr);
260 + (uintmax_t)r->nr);
261 list_refs(r, 0, NULL);
262 r = &header->prerequisites;
263 if (!r->nr) {
264 printf_ln(_("The bundle records a complete history."));
265 } else {
266 printf_ln(Q_("The bundle requires this ref:",
267 - "The bundle requires these %d refs:",
267 + "The bundle requires these %"PRIuMAX" refs:",
268 r->nr),
269 - r->nr);
269 + (uintmax_t)r->nr);
270 list_refs(r, 0, NULL);
271 }
272 }
commit-graph.c
+3 -3
@@ -1690,10 +1690,10 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx,
1690 dirlen = packname.len;
1691 if (ctx->report_progress) {
1692 strbuf_addf(&progress_title,
1693 - Q_("Finding commits for commit graph in %d pack",
1694 - "Finding commits for commit graph in %d packs",
1693 + Q_("Finding commits for commit graph in %"PRIuMAX" pack",
1694 + "Finding commits for commit graph in %"PRIuMAX" packs",
1695 pack_indexes->nr),
1696 - pack_indexes->nr);
1696 + (uintmax_t)pack_indexes->nr);
1697 ctx->progress = start_delayed_progress(progress_title.buf, 0);
1698 ctx->progress_done = 0;
1699 }
mailmap.c
+4 -3
@@ -43,8 +43,8 @@ static void free_mailmap_info(void *p, const char *s)
43 static void free_mailmap_entry(void *p, const char *s)
44 {
45 struct mailmap_entry *me = (struct mailmap_entry *)p;
46 - debug_mm("mailmap: removing entries for <%s>, with %d sub-entries\n",
47 - s, me->namemap.nr);
46 + debug_mm("mailmap: removing entries for <%s>, with %"PRIuMAX" sub-entries\n",
47 + s, (uintmax_t)me->namemap.nr);
48 debug_mm("mailmap: - simple: '%s' <%s>\n",
49 debug_str(me->name), debug_str(me->email));
50
@@ -250,7 +250,8 @@ int read_mailmap(struct string_list *map)
250
251 void clear_mailmap(struct string_list *map)
252 {
253 - debug_mm("mailmap: clearing %d entries...\n", map->nr);
253 + debug_mm("mailmap: clearing %"PRIuMAX" entries...\n",
254 + (uintmax_t)map->nr);
255 map->strdup_strings = 1;
256 string_list_clear_func(map, free_mailmap_entry);
257 debug_mm("mailmap: cleared\n");
merge-ort.c
+2 -2
@@ -4063,8 +4063,8 @@ static void process_entries(struct merge_options *opt,
4063 trace2_region_enter("merge", "process_entries cleanup", opt->repo);
4064 if (dir_metadata.offsets.nr != 1 ||
4065 (uintptr_t)dir_metadata.offsets.items[0].util != 0) {
4066 - printf("dir_metadata.offsets.nr = %d (should be 1)\n",
4067 - dir_metadata.offsets.nr);
4066 + printf("dir_metadata.offsets.nr = %"PRIuMAX" (should be 1)\n",
4067 + (uintmax_t)dir_metadata.offsets.nr);
4068 printf("dir_metadata.offsets.items[0].util = %u (should be 0)\n",
4069 (unsigned)(uintptr_t)dir_metadata.offsets.items[0].util);
4070 fflush(stdout);
string-list.h
+2 -1
@@ -86,7 +86,8 @@ typedef int (*compare_strings_fn)(const char *, const char *);
86 */
87 struct string_list {
88 struct string_list_item *items;
89 - unsigned int nr, alloc;
89 + size_t nr;
90 + size_t alloc;
91 unsigned int strdup_strings:1;
92 compare_strings_fn cmp; /* NULL uses strcmp() */
93 };
t/helper/test-run-command.c
+4 -3
@@ -180,15 +180,16 @@ static int testsuite(int argc, const char **argv)
180 if (max_jobs > suite.tests.nr)
181 max_jobs = suite.tests.nr;
182
183 - fprintf(stderr, "Running %d tests (%d at a time)\n",
184 - suite.tests.nr, max_jobs);
183 + fprintf(stderr, "Running %"PRIuMAX" tests (%d at a time)\n",
184 + (uintmax_t)suite.tests.nr, max_jobs);
185
186 ret = run_processes_parallel(max_jobs, next_test, test_failed,
187 test_finished, &suite);
188
189 if (suite.failed.nr > 0) {
190 ret = 1;
191 - fprintf(stderr, "%d tests failed:\n\n", suite.failed.nr);
191 + fprintf(stderr, "%"PRIuMAX" tests failed:\n\n",
192 + (uintmax_t)suite.failed.nr);
193 for (i = 0; i < suite.failed.nr; i++)
194 fprintf(stderr, "\t%s\n", suite.failed.items[i].string);
195 }
wt-status.c
+6 -6
@@ -1374,10 +1374,10 @@ static void show_rebase_information(struct wt_status *s,
1374 status_printf_ln(s, color, _("No commands done."));
1375 else {
1376 status_printf_ln(s, color,
1377 - Q_("Last command done (%d command done):",
1378 - "Last commands done (%d commands done):",
1377 + Q_("Last command done (%"PRIuMAX" command done):",
1378 + "Last commands done (%"PRIuMAX" commands done):",
1379 have_done.nr),
1380 - have_done.nr);
1380 + (uintmax_t)have_done.nr);
1381 for (i = (have_done.nr > nr_lines_to_show)
1382 ? have_done.nr - nr_lines_to_show : 0;
1383 i < have_done.nr;
@@ -1393,10 +1393,10 @@ static void show_rebase_information(struct wt_status *s,
1393 _("No commands remaining."));
1394 else {
1395 status_printf_ln(s, color,
1396 - Q_("Next command to do (%d remaining command):",
1397 - "Next commands to do (%d remaining commands):",
1396 + Q_("Next command to do (%"PRIuMAX" remaining command):",
1397 + "Next commands to do (%"PRIuMAX" remaining commands):",
1398 yet_to_do.nr),
1399 - yet_to_do.nr);
1399 + (uintmax_t)yet_to_do.nr);
1400 for (i = 0; i < nr_lines_to_show && i < yet_to_do.nr; i++)
1401 status_printf_ln(s, color, " %s", yet_to_do.items[i].string);
1402 if (s->hints)