diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c
index ab779075..7e6fef27 100644
--- a/src/command/cmd_defs.c
+++ b/src/command/cmd_defs.c
@@ -2987,8 +2987,19 @@ command_docgen(void)
cmds = g_list_insert_sorted(cmds, (gpointer)pcmd, (GCompareFunc)_cmp_command);
}
- FILE* toc_fragment = fopen("toc_fragment.html", "w");
- FILE* main_fragment = fopen("main_fragment.html", "w");
+ FILE* toc_fragment = fopen("toc_fragment.html", "w");
+ if (!toc_fragment) {
+ log_error("command_docgen(): unable to open toc_fragment.html for writing: %s", g_strerror(errno));
+ g_list_free(cmds);
+ return;
+ }
+ FILE* main_fragment = fopen("main_fragment.html", "w");
+ if (!main_fragment) {
+ log_error("command_docgen(): unable to open main_fragment.html for writing: %s", g_strerror(errno));
+ fclose(toc_fragment);
+ g_list_free(cmds);
+ return;
+ }
fputs("
- \n", toc_fragment);
fputs("
\n", main_fragment);
@@ -3056,8 +3067,8 @@ command_docgen(void)
fputs("
\n", toc_fragment);
- fclose(toc_fragment);
- fclose(main_fragment);
+ fclose(toc_fragment);
+ fclose(main_fragment);
printf("\nProcessed %d commands.\n\n", g_list_length(cmds));
g_list_free(cmds);
}
@@ -3092,7 +3103,12 @@ command_mangen(void)
log_error("command_mangen(): could not allocate memory");
return;
}
- FILE* manpage = fopen(filename, "w");
+ FILE* manpage = fopen(filename, "w");
+ if (!manpage) {
+ log_error("command_mangen(): unable to open %s for writing: %s", filename, g_strerror(errno));
+ curr = g_list_next(curr);
+ continue;
+ }
fprintf(manpage, "%s\n", header);
fputs(".SH NAME\n", manpage);
@@ -3127,7 +3143,7 @@ command_mangen(void)
}
}
- fclose(manpage);
+ fclose(manpage);
curr = g_list_next(curr);
}
diff --git a/src/database.c b/src/database.c
index 9c3c3000..14837d00 100644
--- a/src/database.c
+++ b/src/database.c
@@ -65,6 +65,36 @@ static gboolean _check_available_space_for_db_migration(char* path_to_db);
static const int latest_version = 2;
+// Helper: close DB handle (if any), warn on busy, and shutdown SQLite
+static void
+_db_teardown(const char* ctx)
+{
+ if (g_chatlog_database) {
+ int rc = sqlite3_close_v2(g_chatlog_database);
+ if (rc != SQLITE_OK) {
+ log_warning("sqlite3_close_v2 in %s returned %d; database may still have active statements.",
+ ctx ? ctx : "db_teardown", rc);
+ }
+ g_chatlog_database = NULL;
+ }
+ sqlite3_shutdown();
+}
+
+// Helper: prepare a statement and log a contextual error on failure
+static gboolean
+_db_prepare_ctx(const char* query, sqlite3_stmt** stmt, const char* ctx)
+{
+ int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, stmt, NULL);
+ if (rc != SQLITE_OK) {
+ log_error("SQLite error in %s: (error code: %d) %s",
+ ctx ? ctx : "sqlite3_prepare_v2",
+ rc,
+ sqlite3_errmsg(g_chatlog_database));
+ return FALSE;
+ }
+ return TRUE;
+}
+
static char*
_db_strdup(const char* str)
{
@@ -106,11 +136,7 @@ log_database_init(ProfAccount* account)
if (ret != SQLITE_OK) {
const char* err_msg = g_chatlog_database ? sqlite3_errmsg(g_chatlog_database) : "(no handle)";
log_error("Error opening SQLite database: %s", err_msg);
- if (g_chatlog_database) {
- sqlite3_close(g_chatlog_database);
- g_chatlog_database = NULL;
- }
- sqlite3_shutdown();
+ _db_teardown("log_database_init(open)");
return FALSE;
}
@@ -222,11 +248,7 @@ out:
} else {
log_error("Unknown SQLite error in log_database_init().");
}
- if (g_chatlog_database) {
- sqlite3_close(g_chatlog_database);
- g_chatlog_database = NULL;
- }
- sqlite3_shutdown();
+ _db_teardown("log_database_init(out)");
return FALSE;
}
@@ -234,14 +256,7 @@ void
log_database_close(void)
{
log_debug("log_database_close() called");
- if (g_chatlog_database) {
- int rc = sqlite3_close_v2(g_chatlog_database);
- if (rc != SQLITE_OK) {
- log_warning("sqlite3_close_v2 returned %d; database may still have active statements.", rc);
- }
- sqlite3_shutdown();
- g_chatlog_database = NULL;
- }
+ _db_teardown("log_database_close");
}
void
@@ -320,9 +335,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las
return msg;
}
- int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL);
- if (rc != SQLITE_OK) {
- log_error("Unknown SQLite error in log_database_get_limits_info().");
+ if (!_db_prepare_ctx(query, &stmt, "log_database_get_limits_info()")) {
if (is_last) {
msg->timestamp = g_date_time_new_now_utc();
}
@@ -387,9 +400,7 @@ log_database_get_previous_chat(const gchar* const contact_barejid, const gchar*
return DB_RESPONSE_ERROR;
}
- int rc = sqlite3_prepare_v2(g_chatlog_database, query, -1, &stmt, NULL);
- if (rc != SQLITE_OK) {
- log_error("SQLite error in log_database_get_previous_chat(): (error code: %d) %s", rc, sqlite3_errmsg(g_chatlog_database));
+ if (!_db_prepare_ctx(query, &stmt, "log_database_get_previous_chat()")) {
return DB_RESPONSE_ERROR;
}
@@ -533,9 +544,7 @@ _add_to_db(ProfMessage* message, char* type, const Jid* const from_jid, const Ji
}
sqlite3_stmt* lmc_stmt = NULL;
-
- if (SQLITE_OK != sqlite3_prepare_v2(g_chatlog_database, replace_check_query, -1, &lmc_stmt, NULL)) {
- log_error("SQLite error in _add_to_db() on selecting original message: %s", sqlite3_errmsg(g_chatlog_database));
+ if (!_db_prepare_ctx(replace_check_query, &lmc_stmt, "_add_to_db(replace_check)")) {
return;
}
@@ -572,8 +581,7 @@ _add_to_db(ProfMessage* message, char* type, const Jid* const from_jid, const Ji
}
sqlite3_stmt* stmt;
-
- if (SQLITE_OK == sqlite3_prepare_v2(g_chatlog_database, duplicate_check_query, -1, &stmt, NULL)) {
+ if (_db_prepare_ctx(duplicate_check_query, &stmt, "_add_to_db(duplicate_check)")) {
if (sqlite3_step(stmt) == SQLITE_ROW) {
log_error("Duplicate stanza-id found for the message. stanza_id: %s; archive_id: %s; sender: %s; content: %s", message->id, message->stanzaid, from_jid->barejid, message->plain);
cons_show_error("Got a message with duplicate (server-generated) stanza-id from %s.", from_jid->fulljid);
@@ -629,8 +637,7 @@ _get_db_version(void)
int current_version = -1;
const char* query = "SELECT `version` FROM `DbVersion` LIMIT 1";
sqlite3_stmt* statement;
-
- if (sqlite3_prepare_v2(g_chatlog_database, query, -1, &statement, NULL) == SQLITE_OK) {
+ if (_db_prepare_ctx(query, &statement, "_get_db_version()")) {
if (sqlite3_step(statement) == SQLITE_ROW) {
current_version = sqlite3_column_int(statement, 0);
}
diff --git a/src/ui/inputwin.c b/src/ui/inputwin.c
index aa68064d..29a63130 100644
--- a/src/ui/inputwin.c
+++ b/src/ui/inputwin.c
@@ -144,10 +144,13 @@ void
create_input_window(void)
{
/* MB_CUR_MAX is evaluated at runtime depending on the current
- * locale, therefore we check that our own version is big enough
- * and bail out if it isn't.
+ * locale; ensure our own compiled-in maximum is sufficient.
+ * Fail gracefully instead of aborting in production.
*/
- assert(MB_CUR_MAX <= PROF_MB_CUR_MAX);
+ 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);
+ return;
+ }
#ifdef NCURSES_REENTRANT
set_escdelay(25);
#else
diff --git a/src/ui/window.c b/src/ui/window.c
index 10a593a6..4968542a 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -75,6 +75,21 @@ static void _win_print_internal(ProfWin* window, const char* show_char, int pad_
int flags, theme_item_t theme_item, const char* const from, const char* const message, DeliveryReceipt* receipt);
static void _win_print_wrapped(WINDOW* win, const char* const message, size_t indent, int pad_indent);
+// Helper: clamp a subwindow width to a sane range [1, cols-1] if possible
+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;
+}
+
int
win_roster_cols(void)
{
@@ -82,12 +97,7 @@ win_roster_cols(void)
int cols = getmaxx(stdscr);
int width = CEILING((((double)cols) / 100) * roster_win_percent);
// Clamp to a sane range to avoid zero/full-width pads
- if (cols > 1) {
- if (width < 1) width = 1;
- if (width >= cols) width = cols - 1;
- } else {
- width = 1;
- }
+ width = _check_subwin_width(cols, width);
return width;
}
@@ -98,12 +108,7 @@ win_occpuants_cols(void)
int cols = getmaxx(stdscr);
int width = CEILING((((double)cols) / 100) * occupants_win_percent);
// Clamp to a sane range to avoid zero/full-width pads
- if (cols > 1) {
- if (width < 1) width = 1;
- if (width >= cols) width = cols - 1;
- } else {
- width = 1;
- }
+ width = _check_subwin_width(cols, width);
return width;
}