diff --git a/src/command/cmd_defs.c b/src/command/cmd_defs.c index ec1e58b3..cf7e6c66 100644 --- a/src/command/cmd_defs.c +++ b/src/command/cmd_defs.c @@ -2988,8 +2988,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); - 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); } @@ -3093,7 +3104,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); @@ -3128,7 +3144,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 b134246f..c4b8c92f 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; }