From 36e2da892308746f020e7d911a1a4de28a08000c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Lo=C3=AFc=20Gomez?= <bip@kyoshiro.org>
Date: Sun, 9 Jan 2022 20:59:59 +0100
Subject: [PATCH 10/24] sanitize: use proper types, safe casts (mostly size_t)

---
 src/bip.c        | 25 +++++++++++--------
 src/connection.c | 65 ++++++++++++++++++++++++++----------------------
 src/connection.h |  8 +++---
 src/irc.c        | 36 ++++++++++++++-------------
 src/irc.h        |  2 +-
 src/line.c       |  7 ++++--
 src/log.c        | 36 ++++++++++++++++-----------
 src/util.c       | 13 ++++++----
 8 files changed, 108 insertions(+), 84 deletions(-)

diff --git a/src/bip.c b/src/bip.c
index 428d101..eae79e2 100644
--- a/src/bip.c
+++ b/src/bip.c
@@ -135,7 +135,7 @@ extern int yyparse(void);
 void conf_die(bip_t *bip, char *fmt, ...)
 {
 	va_list ap;
-	int size = ERRBUFSZ;
+	size_t size = ERRBUFSZ;
 	int n;
 	char *error = bip_malloc(size);
 
@@ -143,12 +143,12 @@ void conf_die(bip_t *bip, char *fmt, ...)
 		va_start(ap, fmt);
 		n = vsnprintf(error, size, fmt, ap);
 		va_end(ap);
-		if (n > -1 && n < size) {
+		if (n > -1 && (unsigned int) n < size) {
 			list_add_last(&bip->errors, error);
 			break;
 		}
 		if (n > -1)
-			size = n + 1;
+			size = (unsigned int) n + 1;
 		else
 			size *= 2;
 		error = bip_realloc(error, size);
@@ -166,7 +166,7 @@ int do_pid_stuff(void)
 	FILE *f;
 	int fd;
 	// size is conf_pid_file + hname max + %ld max + two '.'.
-	int longpath_max = strlen(conf_pid_file) + 512 + 3 + 20;
+	size_t longpath_max = strlen(conf_pid_file) + 512 + 3 + 20;
 	char *longpath = bip_malloc(longpath_max + 1);
 
 try_again:
@@ -1834,7 +1834,7 @@ void set_on_connect_send(struct link_client *ic, char *val)
 
 #define ON_CONNECT_MAX_STRSIZE 1024
 void adm_on_connect_send(struct link_client *ic, struct line *line,
-		unsigned int privmsg)
+		int privmsg)
 {
 	size_t remaining = ON_CONNECT_MAX_STRSIZE;
 	char buf[ON_CONNECT_MAX_STRSIZE];
@@ -1855,12 +1855,12 @@ void adm_on_connect_send(struct link_client *ic, struct line *line,
 	for (i = privmsg + 2; i < irc_line_count(line); i++) {
 		mylog(LOG_DEBUG, "[%s] processing item %d, remaining %ld, %s",
 				LINK(ic)->user->name, i, remaining, buf);
-		if ((unsigned int)i > privmsg + 2)
+		if (i > privmsg + 2)
 			bufpos = bip_strcatf_fit(&remaining, bufpos, " %s",
 					irc_line_elem(line, i));
 		else
 			bufpos = bip_strcat_fit(&remaining, bufpos,
-					(char *)irc_line_elem(line, i));
+					irc_line_elem(line, i));
 		mylog(LOG_DEBUG, "[%s] processed item %d, remaining %ld, %s",
 				LINK(ic)->user->name, i, remaining, buf);
 		if (!bufpos) {
@@ -2008,7 +2008,7 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
 	if (privmsg) {
 		char *linestr, *elemstr;
 		char *ptr, *eptr;
-		int slen;
+		size_t slen;
 
 		if (irc_line_count(line) != 3)
 			return OK_FORGET;
@@ -2020,7 +2020,10 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
 		elemstr = bip_malloc(strlen(linestr) + 1);
 
 		while((eptr = strstr(ptr, " "))) {
-			slen = eptr - ptr;
+			// eptr is either >= ptr or NULL from strstr()
+			// but it can't be NULL per while loop
+			// we can then assume slen is unsigned
+			slen = (size_t)(eptr - ptr);
 			if (slen == 0) {
 				ptr++;
 				continue;
@@ -2030,8 +2033,8 @@ int adm_bip(bip_t *bip, struct link_client *ic, struct line *line, int privmsg)
 			irc_line_append(line, elemstr);
 			ptr = eptr + 1;
 		}
-		eptr = ptr + strlen(ptr);
-		slen = eptr - ptr;
+		slen = strlen(ptr);
+		eptr = ptr + slen;
 		if (slen != 0) {
 			memcpy(elemstr, ptr, slen);
 			elemstr[slen] = 0;
diff --git a/src/connection.c b/src/connection.c
index 92c1747..21e6044 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -206,7 +206,8 @@ static X509 *mySSL_get_cert(SSL *ssl)
 
 static int _write_socket_SSL(connection_t *cn, char* message)
 {
-	int count, size;
+	int count;
+	size_t size;
 
 	size = sizeof(char)*strlen(message);
 
@@ -304,7 +305,7 @@ static int _write_socket(connection_t *cn, char *message)
 		count = write(cn->handle, ((const char *)message) + tcount,
 					size - tcount);
 		if (count > 0) {
-			tcount += count;
+			tcount += (size_t)count;
 			if (tcount == size)
 				return WRITE_OK;
 		}
@@ -805,7 +806,9 @@ static int cn_want_write(connection_t *cn)
 		 * cn->lasttoken is the number of milliseconds when we
 		 * last added a token to the bucket */
 		if (!clock_gettime(CLOCK_MONOTONIC, &tv)) {
-			now = tv.tv_sec * 1000 + tv.tv_nsec / 1000000;
+			if (tv.tv_sec < 0 || tv.tv_nsec < 0)
+				fatal("clock_gettime returned negative time");
+			now = (unsigned long)(tv.tv_sec * 1000 + tv.tv_nsec / 1000000);
 			/* round now to TOKEN_INTERVAL multiple */
 			now -= now % TOKEN_INTERVAL;
 			if (now < cn->lasttoken) {
@@ -813,8 +816,8 @@ static int cn_want_write(connection_t *cn)
 				cn->token = 1;
 				cn->lasttoken = now;
 			} else if (now > cn->lasttoken + TOKEN_INTERVAL) {
-				cn->token += (now - cn->lasttoken) /
-					TOKEN_INTERVAL;
+				cn->token += (unsigned)((now - cn->lasttoken) /
+					TOKEN_INTERVAL);
 				if (cn->token > TOKEN_MAX)
 					cn->token = TOKEN_MAX;
 				if (!cn->token)
@@ -837,7 +840,7 @@ static int cn_want_write(connection_t *cn)
 }
 
 
-list_t *wait_event(list_t *cn_list, int *msec, int *nc)
+list_t *wait_event(list_t *cn_list, time_t *msec, int *nc)
 {
 	fd_set fds_read, fds_write, fds_except;
 	int maxfd = -1, err, errtime;
@@ -1066,7 +1069,7 @@ static void create_listening_socket(char *hostname, char *port,
 
 		if (setsockopt(cn->handle, SOL_SOCKET, SO_REUSEADDR,
 					(char *)&multi_client,
-					sizeof(multi_client)) < 0) {
+					(socklen_t)sizeof(multi_client)) < 0) {
 			mylog(LOG_WARN, "setsockopt() : %s", strerror(errno));
 			close(cn->handle);
 			cn->handle = -1;
@@ -1099,7 +1102,7 @@ static void create_listening_socket(char *hostname, char *port,
 	cn->connected = CONN_ERROR;
 }
 
-static connection_t *connection_init(int anti_flood, int ssl, int timeout,
+static connection_t *connection_init(int anti_flood, int ssl, time_t timeout,
 		int listen)
 {
 	connection_t *conn;
@@ -1141,7 +1144,7 @@ static int ctx_set_dh(SSL_CTX *ctx)
 	/* Return ephemeral DH parameters. */
 	DH *dh = NULL;
 	FILE *f;
-	int ret;
+	long ret;
 
 	if ((f = fopen(conf_client_dh_file, "r")) == NULL) {
 		mylog(LOG_ERROR, "Unable to open DH parameters (%s): %s",
@@ -1272,14 +1275,14 @@ connection_t *listen_new(char *hostname, int port, int ssl)
 	 * SSL flag is only here to tell program to convert socket to SSL after
 	 * accept(). Listening socket will NOT be SSL
 	 */
-	conn = connection_init(0, ssl, 0, 1);
+	conn = connection_init(0, ssl, (time_t)0, 1);
 	create_listening_socket(hostname, portbuf, conn);
 
 	return conn;
 }
 
 static connection_t *_connection_new(char *dsthostname, char *dstport,
-		char *srchostname, char *srcport, int timeout)
+		char *srchostname, char *srcport, time_t timeout)
 {
 	connection_t *conn;
 
@@ -1292,7 +1295,8 @@ static connection_t *_connection_new(char *dsthostname, char *dstport,
 #ifdef HAVE_LIBSSL
 static SSL_CTX *SSL_init_context(char *ciphers)
 {
-	int fd, flags, ret, rng;
+	int fd, flags, rng;
+	ssize_t ret;
 	char buf[1025];
 	SSL_CTX *ctx;
 
@@ -1322,7 +1326,7 @@ static SSL_CTX *SSL_init_context(char *ciphers)
 			}
 			mylog(LOG_DEBUG, "PRNG seeded with %d /dev/random "
 					"bytes", ret);
-			RAND_seed(buf, ret);
+			RAND_seed(buf, (int)ret);
 		} while (!(rng = RAND_status()));
 
 prng_end:
@@ -1426,7 +1430,7 @@ static int bip_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
 	if (!result) {
 		/* We have a verify error! Log it */
 		mylog(LOG_ERROR, "SSL cert check failed at depth=%d: %s (%d)",
-				depth, X509_verify_cert_error_string(err), err);
+				depth, X509_verify_cert_error_string((long)err), err);
 	}
 
 	return result;
@@ -1435,6 +1439,7 @@ static int bip_ssl_verify_callback(int preverify_ok, X509_STORE_CTX *ctx)
 static int SSLize(connection_t *cn, int *nc)
 {
 	int err, err2;
+	long errl;
 
 	if (cn == NULL)
 		return 1;
@@ -1461,7 +1466,7 @@ static int SSLize(connection_t *cn, int *nc)
 	if (err2 == SSL_ERROR_NONE) {
 		const SSL_CIPHER *cipher;
 		char buf[128];
-		int len;
+		size_t len;
 
 		cipher = SSL_get_current_cipher(cn->ssl_h);
 		SSL_CIPHER_description(cipher, buf, 128);
@@ -1480,17 +1485,17 @@ static int SSLize(connection_t *cn, int *nc)
 	case SSL_CHECK_NONE:
 		break;
 	case SSL_CHECK_BASIC:
-		if((err = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
-			mylog(LOG_ERROR, "Certificate check failed: %s (%d)!",
-				X509_verify_cert_error_string(err), err);
+		if((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
+			mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!",
+				X509_verify_cert_error_string(errl), errl);
 			cn->connected = CONN_UNTRUSTED;
 			return 1;
 		}
 		break;
 	case SSL_CHECK_CA:
-		if((err = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
-			mylog(LOG_ERROR, "Certificate check failed: %s (%d)!",
-				X509_verify_cert_error_string(err), err);
+		if((errl = SSL_get_verify_result(cn->ssl_h)) != X509_V_OK) {
+			mylog(LOG_ERROR, "Certificate check failed: %s (%ld)!",
+				X509_verify_cert_error_string(errl), errl);
 			cn->connected = CONN_UNTRUSTED;
 			return 1;
 		}
@@ -1520,7 +1525,7 @@ static int SSLize(connection_t *cn, int *nc)
 
 static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
 		char *srchostname, char *srcport, char *ciphers, int check_mode,
-		char *check_store, char *ssl_client_certfile, int timeout)
+		char *check_store, char *ssl_client_certfile, time_t timeout)
 {
 	connection_t *conn;
 
@@ -1640,7 +1645,7 @@ static connection_t *_connection_new_SSL(char *dsthostname, char *dstport,
 
 connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
 		int srcport, int ssl, char *ssl_ciphers, int ssl_check_mode,
-		char *ssl_check_store, char *ssl_client_certfile, int timeout)
+		char *ssl_check_store, char *ssl_client_certfile, time_t timeout)
 {
 	char dstportbuf[20], srcportbuf[20], *tmp;
 #ifndef HAVE_LIBSSL
@@ -1726,7 +1731,7 @@ int main(int argc,char* argv[])
 		fprintf(stderr,"Usage: %s host port\n",argv[0]);
 		exit(1);
 	}
-	conn = connection_init(0, 0, 0, 1);
+	conn = connection_init(0, 0, (time_t)0, 1);
 	conn->connect_time = time(NULL);
 	create_listening_socket(argv[1],argv[2],&conn);
 	if (s == -1) {
@@ -1754,41 +1759,41 @@ int main(int argc,char* argv[])
 }
 #endif
 
-int connection_localport(connection_t *cn)
+uint16_t connection_localport(connection_t *cn)
 {
 	struct sockaddr_in addr;
 	int err;
 	socklen_t addrlen;
 
 	if (cn->handle <= 0)
-		return -1;
+		return 0;
 
 	addrlen = sizeof(addr);
 	err = getsockname(cn->handle, (struct sockaddr *)&addr, &addrlen);
 	if (err != 0) {
 		mylog(LOG_ERROR, "in getsockname(%d): %s", cn->handle,
 				strerror(errno));
-		return -1;
+		return 0;
 	}
 
 	return ntohs(addr.sin_port);
 }
 
-int connection_remoteport(connection_t *cn)
+uint16_t connection_remoteport(connection_t *cn)
 {
 	struct sockaddr_in addr;
 	int err;
 	socklen_t addrlen;
 
 	if (cn->handle <= 0)
-		return -1;
+		return 0;
 
 	addrlen = sizeof(addr);
 	err = getpeername(cn->handle, (struct sockaddr *)&addr, &addrlen);
 	if (err != 0) {
 		mylog(LOG_ERROR, "in getpeername(%d): %s", cn->handle,
 				strerror(errno));
-		return -1;
+		return 0;
 	}
 
 	return ntohs(addr.sin_port);
diff --git a/src/connection.h b/src/connection.h
index 9e8a254..9058475 100644
--- a/src/connection.h
+++ b/src/connection.h
@@ -92,7 +92,7 @@ typedef struct connection {
 
 connection_t *connection_new(char *dsthostname, int dstport, char *srchostname,
 		int srcport, int ssl, char *ssl_ciphers, int ssl_check_mode,
-		char *ssl_check_store, char *ssl_client_certfile, int timeout);
+		char *ssl_check_store, char *ssl_client_certfile, time_t timeout);
 connection_t *listen_new(char *hostname, int port, int ssl);
 connection_t *accept_new(connection_t *cn);
 void connection_free(connection_t *cn);
@@ -102,13 +102,13 @@ void write_line(connection_t *cn, char *line);
 void write_lines(connection_t *cn, list_t *lines);
 void write_line_fast(connection_t *cn, char *line);
 list_t *read_lines(connection_t *cn, int *error);
-list_t *wait_event(list_t *cn_list, int *msec, int *nc);
+list_t *wait_event(list_t *cn_list, time_t *msec, int *nc);
 
 int cn_is_connected(connection_t *cn);
 int cn_is_listening(connection_t *cn);
 
-int connection_localport(connection_t *cn);
-int connection_remoteport(connection_t *cn);
+uint16_t connection_localport(connection_t *cn);
+uint16_t connection_remoteport(connection_t *cn);
 char *connection_localip(connection_t *cn);
 char *connection_remoteip(connection_t *cn);
 #endif
diff --git a/src/irc.c b/src/irc.c
index dfdc1fa..76c2f4c 100644
--- a/src/irc.c
+++ b/src/irc.c
@@ -53,7 +53,7 @@ static void server_set_chanmodes(struct link_server *l, const char *chanmodes);
 static void server_set_prefix(struct link_server *l, const char *prefix);
 static void server_init_modes(struct link_server *s);
 static int bip_get_index(const char* str, char car);
-static int bip_fls(int v);
+static int bip_fls(long v);
 
 void oidentd_dump(bip_t *bip);
 
@@ -99,7 +99,7 @@ char *nick_from_ircmask(const char *mask)
 		nick++;
 	if (!*nick)
 		return bip_strdup(mask);
-	len = nick - mask;
+	len = (size_t)(nick - mask); // cannot be < 0
 	ret = bip_malloc(len + 1);
 	memcpy(ret, mask, len);
 	ret[len] = 0;
@@ -491,8 +491,8 @@ int irc_dispatch_server(bip_t *bip, struct link_server *server,
 						newnick[7] = '`';
 					}
 				} else {
-					newnick[8] = rand() *
-						('z' - 'a') / RAND_MAX + 'a';
+					newnick[8] = (char)('a' + ('z' - 'a') *
+							rand() / RAND_MAX);
 				}
 				newnick[9] = 0;
 			}
@@ -1123,7 +1123,7 @@ static int irc_cli_join(struct link_client *irc, struct line *line)
 		ks = NULL;
 
 	while ((e = strchr(s, ','))) {
-		size_t len = e - s;
+		size_t len = (size_t)(e - s); // cannot be < 0 or NULL per while
 		char *p = bip_malloc(len + 1);
 		size_t klen;
 		char *kp = NULL;
@@ -1135,7 +1135,7 @@ static int irc_cli_join(struct link_client *irc, struct line *line)
 				ke = strchr(ks, ',');
 				if (!ke)
 					ke = ks + strlen(ks);
-				klen = ke - ks;
+				klen = (size_t)(ke - ks);
 				kp = bip_malloc(klen + 1);
 				memcpy(kp, ks, klen);
 				kp[klen] = 0;
@@ -1495,7 +1495,7 @@ static int irc_353(struct link_server *server, struct line *line)
 		while (*eon && *eon != ' ')
 			eon++;
 
-		len = eon - names;
+		len = (size_t)(eon - names); // cannot be < 0
 		nick = bip_malloc(len + 1);
 		memcpy(nick, names, len);
 		nick[len] = 0;
@@ -1622,7 +1622,7 @@ static int irc_part(struct link_server *server, struct line *line)
 
 static void mode_add_letter_uniq(struct link_server *s, char c)
 {
-	int i;
+	size_t i;
 	for (i = 0; i < s->user_mode_len; i++) {
 		if (s->user_mode[i] == c)
 			return;
@@ -1633,7 +1633,7 @@ static void mode_add_letter_uniq(struct link_server *s, char c)
 
 static void mode_remove_letter(struct link_server *s, char c)
 {
-	int i;
+	size_t i;
 	for (i = 0; i < s->user_mode_len; i++) {
 		if (s->user_mode[i] == c) {
 			for (; i < s->user_mode_len - 1; i++)
@@ -1671,7 +1671,7 @@ static int irc_mode(struct link_server *server, struct line *line)
 	struct channel *channel;
 	const char *mode;
 	int add = 1;
-	unsigned cur_arg = 0;
+	int cur_arg = 0;
 	array_t *mode_args = NULL;
 	int ret;
 
@@ -2347,7 +2347,7 @@ connection_t *irc_server_connect(struct link *link)
 #else
 				0, NULL, 0, NULL, NULL,
 #endif
-				CONNECT_TIMEOUT);
+				(time_t)CONNECT_TIMEOUT);
 	assert(conn);
 	if (conn->handle == -1) {
 		mylog(LOG_INFO, "[%s] Cannot connect.", link->name);
@@ -2697,7 +2697,7 @@ prot_err:
  */
 void irc_main(bip_t *bip)
 {
-	int timeleft = 1000;
+	time_t timeleft = 1000;
 
 	if (bip->reloading_client) {
 		char *l;
@@ -2834,7 +2834,8 @@ static void server_set_chanmodes(struct link_server *l, const char *modes)
 		if (cur || modes) {
 			size_t len;
 			if (cur)
-				len = cur - modes;
+				// cur can't be lower than modes if !NULL
+				len = (size_t)(cur - modes);
 			else
 				len = strlen(modes); // last piece
 			dup = bip_malloc(len + 1);
@@ -2854,7 +2855,7 @@ static void server_set_chanmodes(struct link_server *l, const char *modes)
 static void server_set_prefix(struct link_server *s, const char *modes)
 {
 	char * end_mode;
-	unsigned int len;
+	size_t len;
 
 	mylog(LOG_DEBUG, "[%s] Set user modes", LINK(s)->name);
 
@@ -2866,7 +2867,8 @@ static void server_set_prefix(struct link_server *s, const char *modes)
 		return;
 	}
 
-	len = end_mode - modes - 1; // len of mode without '('
+	// end_mode can't be lower than (modes + 1)
+	len = (size_t)(end_mode - modes - 1); // len of mode without '('
 	if (len * 2 + 2 != strlen(modes)) {
 		mylog(LOG_WARN, "[%s] Unable to parse PREFIX parameter", LINK(s)->name);
 		return;
@@ -2894,9 +2896,9 @@ static int bip_get_index(const char* str, char car)
 		return 0;
 }
 
-static int bip_fls(int v)
+static int bip_fls(long v)
 {
-	unsigned int r = 0;
+	int r = 0;
 	while (v >>= 1)
 		r++;
 
diff --git a/src/irc.h b/src/irc.h
index b3ffaaa..a810c7a 100644
--- a/src/irc.h
+++ b/src/irc.h
@@ -235,7 +235,7 @@ struct link_server {
 	hash_t channels;
 
 	char *user_mode;
-	int user_mode_len;
+	size_t user_mode_len;
 
 	/* init stuff */
 	int lag;
diff --git a/src/line.c b/src/line.c
index 73f35cc..a04f079 100644
--- a/src/line.c
+++ b/src/line.c
@@ -164,7 +164,8 @@ struct line *irc_line_new_from_string(char *str)
 			irc_line_free(line);
 			return NULL;
 		}
-		len = space - str - 1; /* leading ':' */
+		// space is at least str + 1, len >= 0
+		len = (size_t)(space - str - 1); /* leading ':' */
 		line->origin = bip_malloc(len + 1);
 		memcpy(line->origin, str + 1, len);
 		line->origin[len] = 0;
@@ -187,7 +188,9 @@ struct line *irc_line_new_from_string(char *str)
 			while (*space && *space != ' ')
 				space++;
 		}
-		len = space - str;
+		// str is the start of string
+		// space is the end of string or end of word
+		len = (size_t)(space - str);
 		tmp = bip_malloc(len + 1);
 		memcpy(tmp, str, len);
 		tmp[len] = 0;
diff --git a/src/log.c b/src/log.c
index fab405b..ebe7bb5 100644
--- a/src/log.c
+++ b/src/log.c
@@ -27,7 +27,7 @@ extern int conf_log;
 
 extern FILE *conf_global_log_file;
 
-static int _log_write(log_t *logdata, logstore_t *lf, const char *d,
+static size_t _log_write(log_t *logdata, logstore_t *lf, const char *d,
 		const char *str);
 static char *_log_wrap(const char *dest, const char *line);
 void logfile_free(logfile_t *lf);
@@ -72,9 +72,10 @@ int check_dir(char *filename, int is_fatal)
 
 int check_dir_r(char *dirname)
 {
-	int pos, count = 0;
+	size_t count = 0;
 	char *dir, *tmp;
-	int len = strlen(dirname);
+	size_t len = strlen(dirname);
+	size_t pos;
 
 	mylog(LOG_DEBUGVERB, "Recursive check of %s engaged", dirname);
 	tmp = dirname;
@@ -109,7 +110,7 @@ void strtolower(char *str)
 	char *c;
 
 	for (c = str; *c != '\0'; c++)
-		*c = tolower(*c);
+		*c = (char)tolower(*c); // tolower()->int but should be safe to cast
 }
 
 /*
@@ -120,8 +121,8 @@ void strtolower(char *str)
 void replace_var(char *str, char *var, char *value, unsigned int max)
 {
 	char *pos;
-	unsigned int lenvar = strlen(var);
-	unsigned int lenval = strlen(value);
+	size_t lenvar = strlen(var);
+	size_t lenval = strlen(value);
 
 	while((pos = strstr(str, var))) {
 		/* Make room */
@@ -851,14 +852,18 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
 	assert(buf);
 
 	p = strchr(buf, ' ');
+	// buf...p
 	if (!p || !p[0] || !p[1])
 		return _log_wrap(dest, buf);
 	p++;
+	// buf...p
 	sots = logdata->user->backlog_timestamp == BLTSDateTime ? buf : p;
+	// buf...sots=p OR sots=buf...p
 	p = strchr(p, ' ');
+	// buf...sots...p OR sots=buf...p
 	if (!p || !p[0] || !p[1])
 		return _log_wrap(dest, buf);
-	lots = p - sots;
+	lots = (size_t)(p - sots);
 	p++;
 
 	if (strncmp(p, "-!-", (size_t)3) == 0) {
@@ -891,7 +896,7 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
 		p++;
 	if (!p[0])
 		return _log_wrap(dest, buf);
-	lon = p - son;
+	lon = (size_t)(p - son);
 
 	p = strchr(p, ' ');
 	if (!p || !p[0] || !p[1])
@@ -908,10 +913,11 @@ char *log_beautify(log_t *logdata, const char *buf, const char *storename,
 	if (lom == 0)
 		return _log_wrap(dest, buf);
 
+	// action and out are 0 or 1, safe to cast
 	p = ret = (char *)bip_malloc(
 		1 + lon + strlen(LAMESTRING) + strlen(dest) + 2 + lots + 2 +
-		lom + 3 + action * (2 + strlen("ACTION ")) +
-		out * strlen(PMSG_ARROW));
+		lom + 3 + (size_t)action * (2 + strlen("ACTION ")) +
+		(size_t)out * strlen(PMSG_ARROW));
 
 	*p++ = ':';
 
@@ -1024,7 +1030,9 @@ static int log_backread_file(log_t *log, logstore_t *store, logfile_t *lf,
 			/* error or oef */
 			break;
 		}
-		int slen = strlen(buf);
+		size_t slen = strlen(buf);
+		if (slen == 0)
+			break; // should not happen, per previous fgets block
 		if (buf[slen - 1] == '\n')
 			buf[slen - 1] = 0;
 		if (slen >= 2 && buf[slen] == '\r')
@@ -1121,7 +1129,7 @@ static char *_log_wrap(const char *dest, const char *line)
 	return buf;
 }
 
-static int _log_write(log_t *logdata, logstore_t *store,
+static size_t _log_write(log_t *logdata, logstore_t *store,
 		const char *destination, const char *str)
 {
 	size_t nbwrite;
@@ -1246,13 +1254,13 @@ array_t *str_split(const char *str, const char *splt)
 {
 	const char *p = str;
 	const char *start = str;
-	int len;
+	size_t len;
 	char *extracted;
 	array_t *array = array_new();;
 
 	do {
 		if (!*p || strchr(splt, *p)) {
-			len = p - start;
+			len = (size_t)(p - start);
 			extracted = bip_malloc(len + 1);
 			memcpy(extracted, start, len);
 			extracted[len] = 0;
diff --git a/src/util.c b/src/util.c
index 61b67a1..7b4241a 100644
--- a/src/util.c
+++ b/src/util.c
@@ -285,7 +285,7 @@ void mylog(int level, char *fmt, ...)
 void dump_trace(void)
 {
 	void *array[32];
-	size_t size;
+	int size;
 
 	size = backtrace(array, 32);
 	fflush(conf_global_log_file);
@@ -629,8 +629,9 @@ static unsigned char hash_func(const char *pkey)
 	char c;
 	unsigned long hash = 5381; /* 5381 & 0xff makes more sense */
 
+	// toupper should not return negative values (only char compatible int)
 	while ((c = *pkey++))
-		hash = ((hash << 5) + hash) ^ toupper(c);
+		hash = ((hash << 5) + hash) ^ (long unsigned)toupper(c);
 	return (unsigned char)hash;
 }
 
@@ -809,7 +810,7 @@ char *bip_strmaydup(char *s)
 void strucase(char *s)
 {
 	while (*s) {
-		*s = toupper(*s);
+		*s = (char)toupper(*s); // toupper, safe to cast to char
 		s++;
 	}
 }
@@ -839,8 +840,10 @@ void array_ensure(array_t *a, int index)
 
 	if (array_includes(a, index))
 		return;
-	a->elemv = bip_realloc(a->elemv, sizeof(void *) * (index + 1));
-	memset(a->elemv + a->elemc, 0, sizeof(void *) * (index + 1 - a->elemc));
+	a->elemv = bip_realloc(a->elemv, sizeof(void *) * (size_t)(index + 1));
+	// a->elemc should be lower than index + 1
+	memset(a->elemv + a->elemc, 0,
+			sizeof(void *) * (size_t)(index + 1 - a->elemc));
 	a->elemc = index + 1;
 }
 
-- 
2.30.2

