From 22408799569364e8def6571de8998aa51921955d Mon Sep 17 00:00:00 2001 From: Steffen Jaeckel Date: Wed, 18 Mar 2026 13:05:14 +0100 Subject: [PATCH] Fix potential double free. Change `log_database_get_previous_chat()` to not take ownership of `end_time`, so it's clear that whoever passes it in, has to free it. Fixes: https://github.com/profanity-im/profanity/issues/2110 Signed-off-by: Steffen Jaeckel --- src/database.c | 4 ++-- src/database.h | 2 +- src/ui/chatwin.c | 7 ++++--- src/ui/ui.h | 2 +- src/ui/window.c | 4 +--- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/database.c b/src/database.c index 7b59a5b7..60ec5f95 100644 --- a/src/database.c +++ b/src/database.c @@ -296,7 +296,7 @@ log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_las // null the current time is used. from_start gets first few messages if true // otherwise the last ones. Flip flips the order of the results GSList* -log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip) +log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, const char* end_time, gboolean from_start, gboolean flip) { sqlite3_stmt* stmt = NULL; const Jid* myjid = connection_get_jid(); @@ -306,7 +306,7 @@ log_database_get_previous_chat(const gchar* const contact_barejid, const char* s // Flip order when querying older pages gchar* sort1 = from_start ? "ASC" : "DESC"; gchar* sort2 = !flip ? "ASC" : "DESC"; - auto_gchar gchar* end_date_fmt = end_time ? end_time : prof_date_time_format_iso8601(NULL); + auto_gchar gchar* end_date_fmt = end_time ? g_strdup(end_time) : prof_date_time_format_iso8601(NULL); auto_sqlite gchar* query = sqlite3_mprintf("SELECT * FROM (" "SELECT COALESCE(B.`message`, A.`message`) AS message, " "A.`timestamp`, A.`from_jid`, A.`from_resource`, A.`to_jid`, A.`to_resource`, A.`type`, A.`encryption`, A.`stanza_id` FROM `ChatLogs` AS A " diff --git a/src/database.h b/src/database.h index d734282a..dc5312d3 100644 --- a/src/database.h +++ b/src/database.h @@ -21,7 +21,7 @@ void log_database_add_incoming(ProfMessage* message); void log_database_add_outgoing_chat(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); void log_database_add_outgoing_muc_pm(const char* const id, const char* const barejid, const char* const message, const char* const replace_id, prof_enc_t enc); -GSList* log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, char* end_time, gboolean from_start, gboolean flip); +GSList* log_database_get_previous_chat(const gchar* const contact_barejid, const char* start_time, const char* end_time, gboolean from_start, gboolean flip); ProfMessage* log_database_get_limits_info(const gchar* const contact_barejid, gboolean is_last); void log_database_close(void); diff --git a/src/ui/chatwin.c b/src/ui/chatwin.c index f1c53349..1d1311e6 100644 --- a/src/ui/chatwin.c +++ b/src/ui/chatwin.c @@ -558,10 +558,11 @@ _chatwin_history(ProfChatWin* chatwin, const char* const contact_barejid) // first entry's timestamp in the buffer is used. Flip true to prepend to buffer. // Timestamps should be in iso8601 gboolean -chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip) +chatwin_db_history(ProfChatWin* chatwin, const char* start_time, const char* end_time, gboolean flip) { - if (!end_time) { - end_time = buffer_size(((ProfWin*)chatwin)->layout->buffer) == 0 ? NULL : g_date_time_format_iso8601(buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time); + auto_gchar gchar* end_time_ = NULL; + if (!end_time && buffer_size(((ProfWin*)chatwin)->layout->buffer) != 0) { + end_time = end_time_ = g_date_time_format_iso8601(buffer_get_entry(((ProfWin*)chatwin)->layout->buffer, 0)->time); } GSList* history = log_database_get_previous_chat(chatwin->barejid, start_time, end_time, !flip, flip); diff --git a/src/ui/ui.h b/src/ui/ui.h index 8a012931..f47bb906 100644 --- a/src/ui/ui.h +++ b/src/ui/ui.h @@ -119,7 +119,7 @@ void chatwin_set_incoming_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_incoming_char(ProfChatWin* chatwin); void chatwin_set_outgoing_char(ProfChatWin* chatwin, const char* const ch); void chatwin_unset_outgoing_char(ProfChatWin* chatwin); -gboolean chatwin_db_history(ProfChatWin* chatwin, const char* start_time, char* end_time, gboolean flip); +gboolean chatwin_db_history(ProfChatWin* chatwin, const char* start_time, const char* end_time, gboolean flip); // MUC window ProfMucWin* mucwin_new(const char* const barejid); diff --git a/src/ui/window.c b/src/ui/window.c index fb61df1a..178a2c0b 100644 --- a/src/ui/window.c +++ b/src/ui/window.c @@ -682,11 +682,9 @@ win_page_down(ProfWin* window, int scroll_size) if (bf_size != 0) { ProfBuffEntry* last_entry = buffer_get_entry(window->layout->buffer, bf_size - 1); auto_gchar gchar* start = g_date_time_format_iso8601(last_entry->time); - gchar* end_date = prof_date_time_format_iso8601(NULL); + auto_gchar gchar* end_date = prof_date_time_format_iso8601(NULL); if (*scroll_state != WIN_SCROLL_REACHED_BOTTOM && !chatwin_db_history((ProfChatWin*)window, start, end_date, FALSE)) { *scroll_state = WIN_SCROLL_REACHED_BOTTOM; - } else if (*scroll_state == WIN_SCROLL_REACHED_BOTTOM) { - g_free(end_date); } int offset = last_entry->y_end_pos - 1;