mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-25 11:36:21 +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:
@@ -304,8 +304,13 @@ _status_bar_draw_tabs(guint pos)
|
||||
gboolean is_static = g_strcmp0(tabmode, "dynamic") != 0;
|
||||
_get_range_bounds(&start, &end, is_static);
|
||||
|
||||
// if the result of the calc is negative we take 0
|
||||
pos = MAX(0, (getmaxx(stdscr) - (int)_tabs_width(start, end)));
|
||||
guint tabs_w = _tabs_width(start, end);
|
||||
int max_x = getmaxx(stdscr);
|
||||
if (max_x > 0 && (guint)max_x > tabs_w) {
|
||||
pos = (guint)max_x - tabs_w;
|
||||
} else {
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
pos = _status_bar_draw_extended_tabs(pos, TRUE, start, end, is_static);
|
||||
|
||||
@@ -392,7 +397,9 @@ _status_bar_draw_extended_tabs(guint pos, gboolean prefix, guint start, guint en
|
||||
if (prefix && start < 2) {
|
||||
return pos;
|
||||
}
|
||||
if (!prefix && end > opened_tabs - 1) {
|
||||
// Guard against underflow when opened_tabs == 0 (reachable if the
|
||||
// earlier `opened_tabs <= max_tabs` early-return no longer holds).
|
||||
if (!prefix && end >= opened_tabs) {
|
||||
return pos;
|
||||
}
|
||||
gboolean is_current = is_static && statusbar->current_tab > max_tabs;
|
||||
@@ -504,7 +511,7 @@ _status_bar_draw_time(guint pos)
|
||||
int bracket_attrs = theme_attrs(THEME_STATUS_BRACKET);
|
||||
int time_attrs = theme_attrs(THEME_STATUS_TIME);
|
||||
|
||||
size_t len = strlen(statusbar->time);
|
||||
guint len = (guint)strlen(statusbar->time);
|
||||
wattron(statusbar_win, bracket_attrs);
|
||||
mvwaddch(statusbar_win, 0, pos, '[');
|
||||
pos++;
|
||||
@@ -599,7 +606,7 @@ _tabs_width(guint start, guint end)
|
||||
guint opened_tabs = g_hash_table_size(statusbar->tabs);
|
||||
|
||||
int width = start < 2 ? 1 : 4;
|
||||
width += end > opened_tabs - 1 ? 0 : 3;
|
||||
width += (end < opened_tabs) ? 3 : 0;
|
||||
|
||||
if (show_name && show_number) {
|
||||
for (guint i = start; i <= end; i++) {
|
||||
|
||||
Reference in New Issue
Block a user