[#49] harden NULL handling and resource lifecycle across UI and SQLite #47

Manually merged
jabber.developer merged 7 commits from playground/fix/src_refactoring into master 2026-02-06 19:01:48 +00:00
36 changed files with 656 additions and 238 deletions
Showing only changes of commit 56dcb54ffc - Show all commits

View File

@@ -77,6 +77,8 @@ _db_teardown(const char* ctx)
}
g_chatlog_database = NULL;
}
// Safe to call unconditionally; no-op if not initialized.
jabber.developer marked this conversation as resolved Outdated

Earlier it was conditional. Could it cause an issue to have unconditional sqlite3_shutdown?

Also the condition takes almost full function. Maybe it would make sense to use early exit statement if (!g_chatlog_database) return;?

Earlier it was conditional. Could it cause an issue to have unconditional sqlite3_shutdown? Also the condition takes almost full function. Maybe it would make sense to use early exit statement `if (!g_chatlog_database) return;`?

Unconditional sqlite3_shutdown() is safe — it's a no-op if SQLite is already shut down.

https://www.sqlite.org/c3ref/initialize.html

Unconditional sqlite3_shutdown() is safe — it's a no-op if SQLite is already shut down. https://www.sqlite.org/c3ref/initialize.html
// See: https://www.sqlite.org/c3ref/initialize.html
sqlite3_shutdown();
}

View File

@@ -148,7 +148,8 @@ create_input_window(void)
* Fail gracefully instead of aborting in production.
*/
if (MB_CUR_MAX > PROF_MB_CUR_MAX) {
cons_show_error("Your locale's MB_CUR_MAX (%zu) exceeds PROF_MB_CUR_MAX (%d); input window disabled.", (size_t)MB_CUR_MAX, PROF_MB_CUR_MAX);
log_error("Locale MB_CUR_MAX (%zu) exceeds compiled limit (%d)", (size_t)MB_CUR_MAX, PROF_MB_CUR_MAX);
jabber.developer marked this conversation as resolved Outdated

Technically correct, but what user is supposed to do with this data? Can we provide some actionable advise or explanation?

Technically correct, but what user is supposed to do with this data? Can we provide some actionable advise or explanation?

Comment added

Comment added
cons_show_error("Unsupported locale. Before running, execute in terminal: export LC_ALL=C.UTF-8");
return;
}
#ifdef NCURSES_REENTRANT
@@ -167,7 +168,7 @@ create_input_window(void)
inp_win = newpad(1, INP_WIN_MAX);
if (!inp_win) {
jabber.developer marked this conversation as resolved Outdated

Maybe we should add error logging for gracefulness?

Maybe we should add error logging for gracefulness?

Not resolved; no response.

Not resolved; no response.

Added

Added
// Failed to allocate input pad; leave inp_win NULL and avoid further use
log_error("Failed to allocate input window pad");
return;
}
wbkgd(inp_win, theme_attrs(THEME_INPUT_TEXT));

View File

@@ -40,6 +40,8 @@
#include <string.h>
#include <stdlib.h>
#include "log.h"
#ifdef HAVE_NCURSESW_NCURSES_H
#include <ncursesw/ncurses.h>
#elif HAVE_NCURSES_H
@@ -112,6 +114,7 @@ status_bar_init(void)
int row = screen_statusbar_row();
jabber.developer marked this conversation as resolved Outdated

Is it realistic condition? It doesn't appear a normal state, so maybe we should log_warn it?

Is it realistic condition? It doesn't appear a normal state, so maybe we should log_warn it?

Not resolved, as no response given/action taken.

Not resolved, as no response given/action taken.

Added

Added
int cols = getmaxx(stdscr);
if (cols <= 0) {
log_warning("status_bar_init: invalid cols %d, defaulting to 1", cols);
cols = 1;
}
statusbar_win = newwin(1, cols, row, 0);
@@ -157,6 +160,7 @@ status_bar_resize(void)
}
int cols = getmaxx(stdscr);
if (cols <= 0) {
log_warning("status_bar_resize: invalid cols %d, defaulting to 1", cols);
cols = 1;
}
werase(statusbar_win);

View File

@@ -79,15 +79,7 @@ static void _win_print_wrapped(WINDOW* win, const char* const message, size_t in
static int
_check_subwin_width(int cols, int width)
{
if (cols > 1) {
if (width < 1)
width = 1;
if (width >= cols)
width = cols - 1;
} else {
width = 1;
}
return width;
return cols <= 1 ? 1 : CLAMP(width, 1, cols - 1);
jabber.developer marked this conversation as resolved Outdated

Why not like this?

return cols <= 1 ? 1 : CLAMP(width, 1, cols - 1);
Why not like this? ```c return cols <= 1 ? 1 : CLAMP(width, 1, cols - 1); ```

Corrected

Corrected
}
int