diff mbox series

[06/10] global: fix unsigned integer promotions in ternary statements

Message ID 20241129-pks-sign-compare-v1-6-fc406b984bc9@pks.im (mailing list archive)
State New
Headers show
Series Start compiling with `-Wsign-compare` | expand

Commit Message

Patrick Steinhardt Nov. 29, 2024, 1:13 p.m. UTC
We have several cases in our codebase where the ternary operator changes
signedness from a signed integer type to an unsigned one. This causes
warnings with `-Wsign-compare`. Generally, we seem to have three classes
of this in our codebase:

  - Cases where we know that the result is well-formed, e.g. when
    indexing into strings to determine the length of substrings.

  - Cases where we want `-1` to mean "unlimited", counting on the
    wrap-around.

  - Cases where we may indeed run into problems when one of the
    statements returns a value that is too big.

Out of these only the last class is a bit worrying, but we can address
it by adding a call to `cast_size_t_to_int()`. Like this we're better
protected in case we have unexpectedly huge input as we'd die instead of
silently doing the wrong thing.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
---
 builtin/blame.c           | 3 ++-
 builtin/patch-id.c        | 2 +-
 dir.c                     | 4 ++--
 gettext.c                 | 4 +---
 gpg-interface.c           | 2 +-
 scalar.c                  | 2 +-
 strbuf.c                  | 2 +-
 t/helper/test-csprng.c    | 4 +---
 t/helper/test-genrandom.c | 4 +---
 9 files changed, 11 insertions(+), 16 deletions(-)
diff mbox series

Patch

diff --git a/builtin/blame.c b/builtin/blame.c
index f0d209791e44025b1965cd447cf4fc1e2ca5f009..6c6b0c7ef1a4d992064c7664bbf1229ef0286b97 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -470,7 +470,8 @@  static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int
 
 	for (cnt = 0; cnt < ent->num_lines; cnt++) {
 		char ch;
-		int length = (opt & OUTPUT_LONG_OBJECT_NAME) ? the_hash_algo->hexsz : abbrev;
+		int length = (opt & OUTPUT_LONG_OBJECT_NAME) ?
+			cast_size_t_to_int(the_hash_algo->hexsz) : abbrev;
 
 		if (opt & OUTPUT_COLOR_LINE) {
 			if (cnt > 0) {
diff --git a/builtin/patch-id.c b/builtin/patch-id.c
index 56585757477911c96bbb9ef2cf3710691b8e744e..87fa586c4d552ba61cd2ac2cf079d68241eb3275 100644
--- a/builtin/patch-id.c
+++ b/builtin/patch-id.c
@@ -163,7 +163,7 @@  static int get_one_patchid(struct object_id *next_oid, struct object_id *result,
 			after--;
 
 		/* Add line to hash algo (possibly removing whitespace) */
-		len = verbatim ? strlen(line) : remove_space(line);
+		len = verbatim ? cast_size_t_to_int(strlen(line)) : remove_space(line);
 		patchlen += len;
 		the_hash_algo->update_fn(&ctx, line, len);
 	}
diff --git a/dir.c b/dir.c
index 5b2181e5899ce951791aa5e46ccdbb2d71ce6144..fc77ffe56c9d8353d918553223f5521fa3bc3a94 100644
--- a/dir.c
+++ b/dir.c
@@ -1643,7 +1643,7 @@  static void prep_exclude(struct dir_struct *dir,
 		strbuf_init(&dir->internal.basebuf, PATH_MAX);
 
 	/* Read from the parent directories and push them down. */
-	current = stk ? stk->baselen : -1;
+	current = stk ? cast_size_t_to_int(stk->baselen) : -1;
 	strbuf_setlen(&dir->internal.basebuf, current < 0 ? 0 : current);
 	if (dir->untracked)
 		untracked = stk ? stk->ucd : dir->untracked->root;
@@ -2896,7 +2896,7 @@  static void new_untracked_cache(struct index_state *istate, int flags)
 	struct untracked_cache *uc = xcalloc(1, sizeof(*uc));
 	strbuf_init(&uc->ident, 100);
 	uc->exclude_per_dir = ".gitignore";
-	uc->dir_flags = flags >= 0 ? flags : new_untracked_cache_flags(istate);
+	uc->dir_flags = flags >= 0 ? (unsigned) flags : new_untracked_cache_flags(istate);
 	set_untracked_ident(uc);
 	istate->untracked = uc;
 	istate->cache_changed |= UNTRACKED_CHANGED;
diff --git a/gettext.c b/gettext.c
index 8d08a61f8487dc30559e5e5d6d31cf06a92789e1..ecb0c70c1144ce8b4280b78a2b443138e8af6603 100644
--- a/gettext.c
+++ b/gettext.c
@@ -2,8 +2,6 @@ 
  * Copyright (c) 2010 Ævar Arnfjörð Bjarmason
  */
 
-#define DISABLE_SIGN_COMPARE_WARNINGS
-
 #include "git-compat-util.h"
 #include "abspath.h"
 #include "environment.h"
@@ -135,7 +133,7 @@  int gettext_width(const char *s)
 	if (is_utf8 == -1)
 		is_utf8 = is_utf8_locale();
 
-	return is_utf8 ? utf8_strwidth(s) : strlen(s);
+	return is_utf8 ? utf8_strwidth(s) : cast_size_t_to_int(strlen(s));
 }
 #endif
 
diff --git a/gpg-interface.c b/gpg-interface.c
index a67d80475bf9d8452de0c3ae9bb08ceeb4c11c4b..e1720361f17e8b3b3315f0a5d93a827e11b2b036 100644
--- a/gpg-interface.c
+++ b/gpg-interface.c
@@ -700,7 +700,7 @@  size_t parse_signed_buffer(const char *buf, size_t size)
 			match = len;
 
 		eol = memchr(buf + len, '\n', size - len);
-		len += eol ? eol - (buf + len) + 1 : size - len;
+		len += eol ? (size_t) (eol - (buf + len) + 1) : size - len;
 	}
 	return match;
 }
diff --git a/scalar.c b/scalar.c
index 87bb30991bf768534a988608d9b194dc8b5ba78a..ce18fab07c08be715142379fd9d757e96c554fbb 100644
--- a/scalar.c
+++ b/scalar.c
@@ -380,7 +380,7 @@  static int delete_enlistment(struct strbuf *enlistment)
 	offset = offset_1st_component(enlistment->buf);
 	path_sep = find_last_dir_sep(enlistment->buf + offset);
 	strbuf_add(&parent, enlistment->buf,
-		   path_sep ? path_sep - enlistment->buf : offset);
+		   path_sep ? (size_t) (path_sep - enlistment->buf) : offset);
 	if (chdir(parent.buf) < 0) {
 		int res = error_errno(_("could not switch to '%s'"), parent.buf);
 		strbuf_release(&parent);
diff --git a/strbuf.c b/strbuf.c
index 8ddd4b06c595ac3f8b38a65d3e1ca4b340fddf9f..8c027a67942a72b9078c7f6e144c883c76d461d4 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -1055,7 +1055,7 @@  void strbuf_stripspace(struct strbuf *sb, const char *comment_prefix)
 
 	for (i = j = 0; i < sb->len; i += len, j += newlen) {
 		eol = memchr(sb->buf + i, '\n', sb->len - i);
-		len = eol ? eol - (sb->buf + i) + 1 : sb->len - i;
+		len = eol ? (size_t) (eol - (sb->buf + i) + 1) : sb->len - i;
 
 		if (comment_prefix && len &&
 		    starts_with(sb->buf + i, comment_prefix)) {
diff --git a/t/helper/test-csprng.c b/t/helper/test-csprng.c
index ea9b9b656307d32bdc1f2e15a91793b1dda9c463..31dbe7db4ac61639541f15d262cea64368fec78f 100644
--- a/t/helper/test-csprng.c
+++ b/t/helper/test-csprng.c
@@ -1,5 +1,3 @@ 
-#define DISABLE_SIGN_COMPARE_WARNINGS
-
 #include "test-tool.h"
 #include "git-compat-util.h"
 
@@ -14,7 +12,7 @@  int cmd__csprng(int argc, const char **argv)
 		return 2;
 	}
 
-	count = (argc == 2) ? strtoul(argv[1], NULL, 0) : -1L;
+	count = (argc == 2) ? strtoul(argv[1], NULL, 0) : (unsigned long) -1L;
 
 	while (count) {
 		unsigned long chunk = count < sizeof(buf) ? count : sizeof(buf);
diff --git a/t/helper/test-genrandom.c b/t/helper/test-genrandom.c
index 5b51e6648d8e698b09f400efcf67a0708c226e9d..efca20e7efff46bf66c2b8888ce88db02e545cd5 100644
--- a/t/helper/test-genrandom.c
+++ b/t/helper/test-genrandom.c
@@ -4,8 +4,6 @@ 
  * Copyright (C) 2007 by Nicolas Pitre, licensed under the GPL version 2.
  */
 
-#define DISABLE_SIGN_COMPARE_WARNINGS
-
 #include "test-tool.h"
 #include "git-compat-util.h"
 
@@ -24,7 +22,7 @@  int cmd__genrandom(int argc, const char **argv)
 		next = next * 11 + *c;
 	} while (*c++);
 
-	count = (argc == 3) ? strtoul(argv[2], NULL, 0) : -1L;
+	count = (argc == 3) ? strtoul(argv[2], NULL, 0) : (unsigned long) -1L;
 
 	while (count--) {
 		next = next * 1103515245 + 12345;