git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 4/4] convert: use size_t for text statistics and ident counts

From
Elia Pinto <gitter.spiros@gmail.com>
Date
Oct 30, 2026, 09:58 UTC
Message-ID
<84e9e38a3e63a2b135847471a13ea36d37bd64d4.1793352943.git.gitter.spiros@gmail.com>
In-Reply-To
<cover.1793352943.git.gitter.spiros@gmail.com>

gather_stats() counts NULs, CRs, LFs, CRLFs and (non)printable characters in "unsigned" fields of struct text_stat, and count_ident() counts "$Id$" markers in an "int". Now that the buffer sizes they work on are size_t, a large enough buffer overflows them. Unlike the previous patches, this is not specific to LLP64: "unsigned" is 32 bits wide on all the platforms we care about.

The counters only drive decisions, but a wrapped counter makes the wrong one. For example, a file with exactly 2^32 lone LFs gets lonelf == 0, so will_convert_lf_to_crlf() decides there is nothing to convert, and a wrapped "printable" or "nonprintable" can fool the heuristic in convert_is_binary(). In count_ident(), going past INT_MAX is undefined behaviour.

This is not a memory safety problem: the counts are only used as hints to strbuf_grow() in crlf_to_worktree() and ident_to_worktree(), and the buffers are then filled with strbuf_add(), which grows them as needed.

Use size_t for all of them, and compute the size hint in ident_to_worktree() with st_add() and st_mult(), so that it dies instead of wrapping around.

Triggering any of this needs more than 4GiB of input, so no test is added.

Suggested-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Elia Pinto <gitter.spiros@gmail.com>
---
 convert.c | 12 ++++++------
 1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/convert.c b/convert.c
index ca5594cab0..34fb4ce685 100644
--- a/convert.c
+++ b/convert.c
@@ -36,10 +36,10 @@
 
 struct text_stat {
 	/* NUL, CR, LF and CRLF counts */
-	unsigned nul, lonecr, lonelf, crlf;
+	size_t nul, lonecr, lonelf, crlf;
 
 	/* These are just approximations! */
-	unsigned printable, nonprintable;
+	size_t printable, nonprintable;
 };
 
 static void gather_stats(const char *buf, size_t size, struct text_stat *stats)
@@ -1077,12 +1077,12 @@ static int read_convert_config(const char *var, const char *value,
 	return 0;
 }
 
-static int count_ident(const char *cp, size_t size)
+static size_t count_ident(const char *cp, size_t size)
 {
 	/*
 	 * "$Id: 0000000000000000000000000000000000000000 $" <=> "$Id$"
 	 */
-	int cnt = 0;
+	size_t cnt = 0;
 	char ch;
 
 	while (size) {
@@ -1170,7 +1170,7 @@ static int ident_to_worktree(const char *src, size_t len,
 	struct object_id oid;
 	char *to_free = NULL;
 	const char *dollar, *spc;
-	int cnt;
+	size_t cnt;
 
 	if (!ident)
 		return 0;
@@ -1184,7 +1184,7 @@ static int ident_to_worktree(const char *src, size_t len,
 		to_free = strbuf_detach(buf, NULL);
 	hash_object_file(the_hash_algo, src, len, OBJ_BLOB, &oid);
 
-	strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3));
+	strbuf_grow(buf, st_add(len, st_mult(cnt, the_hash_algo->hexsz + 3)));
 	for (;;) {
 		/* step 1: run to the next '$' */
 		dollar = memchr(src, '$', len);
-- 
2.53.0
Previous: Elia PintoNext: Patrick Steinhardt
Message 14 of 22 in “use size_t for a few more object and buffer sizes”
  1. 0/3 use size_t for a few more object and buffer sizesElia Pinto, Oct 21, 2026
  2. 1/3 odb: use size_t for the length of objects to writeElia Pinto, Oct 21, 2026
  3. Patrick SteinhardtOct 21, 2026
  4. 2/3 diff: use size_t for the allocation size of word-diff buffersElia Pinto, Oct 21, 2026
  5. Patrick SteinhardtOct 21, 2026
  6. 3/3 convert: use size_t for buffer sizesElia Pinto, Oct 21, 2026
  7. Patrick SteinhardtOct 21, 2026
  8. 0/4 use size_t for a few more object and buffer sizesElia Pinto, Oct 30, 2026
  9. 1/4 odb: use size_t for the length of objects to writeElia Pinto, Oct 30, 2026
  10. Patrick SteinhardtOct 30, 2026
  11. Elia PintoOct 31, 2026
  12. 2/4 diff: use size_t for the allocation size of word-diff buffersElia Pinto, Oct 30, 2026
  13. 3/4 convert: use size_t for buffer sizesElia Pinto, Oct 30, 2026
  14. 4/4 convert: use size_t for text statistics and ident countsElia Pinto, Oct 30, 2026
  15. Patrick SteinhardtOct 30, 2026
  16. Elia PintoOct 31, 2026
  17. Patrick SteinhardtNov 2, 2026
  18. 0/4 use size_t for a few more object and buffer sizesElia Pinto, Oct 31, 2026
  19. 1/4 odb: use size_t for the length of objects to writeElia Pinto, Oct 31, 2026
  20. 2/4 diff: use size_t for the allocation size of word-diff buffersElia Pinto, Oct 31, 2026
  21. 3/4 convert: use size_t for buffer sizesElia Pinto, Oct 31, 2026
  22. 4/4 convert: use size_t for text statistics and ident countsElia Pinto, Oct 31, 2026

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.