mirror of
https://github.com/profanity-im/profanity.git
synced 2025-01-03 14:57:42 -05:00
Only handle MAM response if window still exists
Before this patch the following scenario lead to a segfault: 1. open a window that sends a MAM request 2. fast enough close that window again before the MAM response was processed Once the MAM response is received we'd call `_mam_rsm_id_handler()` from the `_iq_handler()` and `window` would point to a non-existant window which leads to a segfault. Signed-off-by: Steffen Jaeckel <jaeckel-floss@eyet-services.de>
This commit is contained in:
parent
f003667d6a
commit
6116702dd2
@ -712,6 +712,8 @@ ui_close_win(int index)
|
||||
}
|
||||
}
|
||||
|
||||
// remove the IQ handlers
|
||||
iq_handlers_remove_win(window);
|
||||
wins_close_by_num(index);
|
||||
title_bar_console();
|
||||
status_bar_current(1);
|
||||
|
@ -267,6 +267,54 @@ iq_handlers_init(void)
|
||||
rooms_cache = g_hash_table_new_full(g_str_hash, g_str_equal, free, (GDestroyNotify)xmpp_stanza_release);
|
||||
}
|
||||
|
||||
struct iq_win_finder
|
||||
{
|
||||
gsize max, cur;
|
||||
char** to_be_removed;
|
||||
};
|
||||
|
||||
static void
|
||||
_win_find(char* key,
|
||||
ProfIqHandler* handler,
|
||||
struct iq_win_finder* finder)
|
||||
{
|
||||
if (handler->func == _mam_rsm_id_handler) {
|
||||
if (finder->cur >= finder->max) {
|
||||
finder->max *= 2;
|
||||
finder->to_be_removed = g_realloc_n(finder->to_be_removed, finder->max, sizeof(char*));
|
||||
}
|
||||
finder->to_be_removed[finder->cur++] = g_strdup(key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
iq_handlers_remove_win(ProfWin* window)
|
||||
{
|
||||
log_debug("Remove window %p of type %d", window, window ? window->type : -1);
|
||||
if (!window)
|
||||
return;
|
||||
GSList *cur = late_delivery_windows, *next;
|
||||
while (cur) {
|
||||
LateDeliveryUserdata* del_data = cur->data;
|
||||
next = g_slist_next(cur);
|
||||
if (del_data->win == (void*)window)
|
||||
late_delivery_windows = g_slist_delete_link(late_delivery_windows,
|
||||
cur);
|
||||
cur = next;
|
||||
}
|
||||
struct iq_win_finder st = { 0 };
|
||||
st.max = g_hash_table_size(id_handlers);
|
||||
if (st.max == 0)
|
||||
return;
|
||||
st.to_be_removed = g_new(char*, st.max);
|
||||
g_hash_table_foreach(id_handlers, (GHFunc)_win_find, &st);
|
||||
for (gsize n = 0; n < st.cur; ++n) {
|
||||
g_hash_table_remove(id_handlers, st.to_be_removed[n]);
|
||||
g_free(st.to_be_removed[n]);
|
||||
}
|
||||
g_free(st.to_be_removed);
|
||||
}
|
||||
|
||||
void
|
||||
iq_handlers_clear()
|
||||
{
|
||||
@ -2696,6 +2744,10 @@ _mam_rsm_id_handler(xmpp_stanza_t* const stanza, void* const userdata)
|
||||
gboolean is_complete = g_strcmp0(xmpp_stanza_get_attribute(fin, "complete"), "true") == 0;
|
||||
MamRsmUserdata* data = (MamRsmUserdata*)userdata;
|
||||
ProfWin* window = (ProfWin*)data->win;
|
||||
if (wins_get_num(window) == -1) {
|
||||
log_error("Window %p should not get any events anymore", window);
|
||||
return 0;
|
||||
}
|
||||
|
||||
buffer_remove_entry(window->layout->buffer, 0);
|
||||
|
||||
|
@ -240,6 +240,7 @@ void iq_enable_carbons(void);
|
||||
void iq_disable_carbons(void);
|
||||
void iq_send_software_version(const char* const fulljid);
|
||||
void iq_rooms_cache_clear(void);
|
||||
void iq_handlers_remove_win(ProfWin* window);
|
||||
void iq_handlers_clear();
|
||||
void iq_room_list_request(gchar* conferencejid, gchar* filter);
|
||||
void iq_disco_info_request(gchar* jid);
|
||||
|
Loading…
Reference in New Issue
Block a user