mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-22 00:56:22 +00:00
refactor: clean narrowing conversions and harden unsigned arithmetic
Cleanup of the conversion-safety warnings exposed by enabling -Wconversion / -Wsign-compare in the previous commit, plus guard clauses at the few places where unsigned arithmetic could actually misbehave. Build: - configure.ac drops -Wno-error=conversion and -Wno-error=float-conversion. Only -Wno-error=sign-conversion and -Wno-error=sign-compare remain, gating the ~230 sign warnings inherited from upstream that will be cleaned up in follow-ups. Type / conversion fixes (no behaviour change): - Length-like locals in command/cmd_ac.c, command/cmd_funcs.c, pgp/gpg.c, tools/autocomplete.c, tools/parser.c and ui/mucwin.c switched from int to size_t / glong (matching strlen / g_utf8_strlen return type) so we no longer need an (int) cast and loop counters / array sizes stay in their natural unsigned domain. - g_timer_elapsed / GTimeSpan -> int casts in session.c, iq.c, core.c, server_events.c, window.c. - _win_print_wrapped: indent parameter and local curx/maxx switched from size_t to int to match _win_indent / getcurx / getmaxx. - Port casts (int -> unsigned short) at the libstrophe boundary in connection.c and session.c, each preceded by g_assert(port >= 0 && port <= UINT16_MAX) so the truncation is documented at the call-site. - curl_off_t / fread size_t results cast at usage in http_upload.c, http_download.c, omemo/crypto.c. - strtoul results cast to uint32_t in xmpp/omemo.c and omemo/omemo.c where device/prekey IDs are genuinely 32-bit. - config/color.c: fg/bg/palette indices switched to `short` end-to-end (find_col, color_hash, find_closest_col, _color_pair_cache_get, cache.pairs), so the ncurses init_pair boundary needs at most one (short)i cast for the cache index. Also TODO-noted: init_extended_pair is needed for >15-bit palettes. - xmpp/avatar.c: float arithmetic explicitly casts its int operands. - tests/functionaltests/proftest.c: read() result handling uses size_t for the accumulator, _read_output returns ssize_t, and the buffer-shift check happens before space subtraction so the expression cannot underflow. Real-risk guard clauses (the part that actually fixes bugs): - src/ui/statusbar.c _tabs_width: `end > opened_tabs - 1` rewritten as `end < opened_tabs` so opened_tabs == 0 no longer underflows. - src/ui/statusbar.c _status_bar_draw_extended_tabs: the mirror comparison rewritten as `end >= opened_tabs`. - src/ui/statusbar.c status_bar_draw: replaced `MAX(0, getmaxx - (int)_tabs_width)` with an explicit precheck before subtraction. - src/omemo/omemo.c prekey selection: prekey_index is now uint32_t and randomized into an unsigned buffer, so modulo with prekeys_len cannot yield a negative index for g_list_nth_data. - src/omemo/crypto.c omemo_decrypt_func: PKCS#5/PKCS#7 unpadding reads `plaintext[plaintext_len - 1]`, which would underflow on a malformed empty ciphertext and read past the heap buffer. Reject plaintext_len == 0 before the padding peek and validate the padding byte against the buffer length before the unpad loop. Initialise plaintext = NULL so the early `goto out` cannot free uninitialised memory. - src/ui/inputwin.c (4 mbrlen sites) and src/ui/window.c _win_print_wrapped: mbrlen() returns 0 for the null wide character. The existing checks rejected (size_t)-1 / -2 but treated 0 as a valid step, so the surrounding loops would either advance by SIZE_MAX (i += ch_len - 1) or spin in place (word_pos += 0 forever). Add `|| ch_len == 0` to each guard; inside the spell-check word-emission loop also fall back to a one-byte advance. - Defensive `len > 0 ? len - 1 : 0` prechecks at the strlen-based g_strndup / loop sites in ui/console.c, plugins/c_api.c and plugins/python_plugins.c.
This commit is contained in:
@@ -290,7 +290,7 @@ autocomplete_complete(Autocomplete ac, const gchar* search_str, gboolean quote,
|
||||
static char*
|
||||
_autocomplete_param_common(const char* const input, char* command, autocomplete_func func, Autocomplete ac, gboolean quote, gboolean previous, void* context)
|
||||
{
|
||||
int len;
|
||||
size_t len;
|
||||
auto_gchar gchar* command_cpy = g_strdup_printf("%s ", command);
|
||||
if (!command_cpy) {
|
||||
return NULL;
|
||||
@@ -299,14 +299,14 @@ _autocomplete_param_common(const char* const input, char* command, autocomplete_
|
||||
len = strlen(command_cpy);
|
||||
|
||||
if (strncmp(input, command_cpy, len) == 0) {
|
||||
int inp_len = strlen(input);
|
||||
size_t inp_len = strlen(input);
|
||||
auto_char char* found = NULL;
|
||||
auto_char char* prefix = malloc(inp_len + 1);
|
||||
if (!prefix) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (int i = len; i < inp_len; i++) {
|
||||
for (size_t i = len; i < inp_len; i++) {
|
||||
prefix[i - len] = input[i];
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ _xferinfo(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultot
|
||||
|
||||
unsigned int dlperc = 0;
|
||||
if (dltotal != 0) {
|
||||
dlperc = (100 * dlnow) / dltotal;
|
||||
dlperc = (unsigned int)((100 * dlnow) / dltotal);
|
||||
}
|
||||
|
||||
if (!download->silent) {
|
||||
|
||||
@@ -62,7 +62,7 @@ _xferinfo(void* userdata, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultot
|
||||
|
||||
unsigned int ulperc = 0;
|
||||
if (ultotal != 0) {
|
||||
ulperc = (100 * ulnow) / ultotal;
|
||||
ulperc = (unsigned int)((100 * ulnow) / ultotal);
|
||||
}
|
||||
|
||||
gchar* msg = NULL;
|
||||
|
||||
@@ -28,7 +28,7 @@ _parse_args_helper(const char* const inp, int min, int max, gboolean* result, gb
|
||||
auto_char char* copy = strdup(inp);
|
||||
g_strstrip(copy);
|
||||
|
||||
int inp_size = g_utf8_strlen(copy, -1);
|
||||
glong inp_size = g_utf8_strlen(copy, -1);
|
||||
gboolean in_token = FALSE;
|
||||
gboolean in_freetext = FALSE;
|
||||
gboolean in_quotes = FALSE;
|
||||
@@ -37,7 +37,7 @@ _parse_args_helper(const char* const inp, int min, int max, gboolean* result, gb
|
||||
GSList* tokens = NULL;
|
||||
|
||||
// add tokens to GSList
|
||||
for (int i = 0; i < inp_size; i++) {
|
||||
for (glong i = 0; i < inp_size; i++) {
|
||||
gchar* curr_ch = g_utf8_offset_to_pointer(copy, i);
|
||||
gunichar curr_uni = g_utf8_get_char(curr_ch);
|
||||
|
||||
@@ -231,10 +231,10 @@ gchar**
|
||||
parse_args_as_one(const char* const inp, int min, int max, gboolean* result)
|
||||
{
|
||||
gchar** args = g_malloc0(2 * sizeof(*args));
|
||||
int length = g_utf8_strlen(inp, -1);
|
||||
glong length = g_utf8_strlen(inp, -1);
|
||||
gchar* space = g_utf8_strchr(inp, length, ' ');
|
||||
if (space) {
|
||||
int sub_length = g_utf8_strlen(space, -1);
|
||||
glong sub_length = g_utf8_strlen(space, -1);
|
||||
if (sub_length > 1) {
|
||||
args[0] = g_strdup(space + 1);
|
||||
*result = TRUE;
|
||||
@@ -253,14 +253,14 @@ parse_args_as_one(const char* const inp, int min, int max, gboolean* result)
|
||||
int
|
||||
count_tokens(const char* const string)
|
||||
{
|
||||
int length = g_utf8_strlen(string, -1);
|
||||
glong length = g_utf8_strlen(string, -1);
|
||||
gboolean in_quotes = FALSE;
|
||||
int num_tokens = 0;
|
||||
|
||||
// include first token
|
||||
num_tokens++;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (glong i = 0; i < length; i++) {
|
||||
gchar* curr_ch = g_utf8_offset_to_pointer(string, i);
|
||||
gunichar curr_uni = g_utf8_get_char(curr_ch);
|
||||
|
||||
@@ -298,14 +298,14 @@ char*
|
||||
get_start(const char* const string, int tokens)
|
||||
{
|
||||
GString* result = g_string_new("");
|
||||
int length = g_utf8_strlen(string, -1);
|
||||
glong length = g_utf8_strlen(string, -1);
|
||||
gboolean in_quotes = FALSE;
|
||||
int num_tokens = 0;
|
||||
|
||||
// include first token
|
||||
num_tokens++;
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
for (glong i = 0; i < length; i++) {
|
||||
gchar* curr_ch = g_utf8_offset_to_pointer(string, i);
|
||||
gunichar curr_uni = g_utf8_get_char(curr_ch);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user