diff options
-rw-r--r-- | src/common/hexchat.c | 2 | ||||
-rw-r--r-- | src/common/plugin.c | 48 |
2 files changed, 39 insertions, 11 deletions
diff --git a/src/common/hexchat.c b/src/common/hexchat.c index 3ba7ed6d..a2e88a0d 100644 --- a/src/common/hexchat.c +++ b/src/common/hexchat.c @@ -183,7 +183,7 @@ lastact_getfirst(int (*filter) (session *sess)) int is_session (session * sess) { - return g_slist_find (sess_list, sess) ? 1 : 0; + return sess != NULL && (g_slist_find (sess_list, sess) ? 1 : 0); } session * diff --git a/src/common/plugin.c b/src/common/plugin.c index 40e55bbf..d3f3b7ca 100644 --- a/src/common/plugin.c +++ b/src/common/plugin.c @@ -574,10 +574,13 @@ static int plugin_hook_run (session *sess, char *name, char *word[], char *word_eol[], hexchat_event_attrs *attrs, int type) { + /* fix segfault https://github.com/hexchat/hexchat/issues/2265 */ + static int depth = 0; GSList *list, *next; hexchat_hook *hook; int ret, eat = 0; + depth++; list = hook_list; while (1) { @@ -623,18 +626,22 @@ plugin_hook_run (session *sess, char *name, char *word[], char *word_eol[], } xit: - /* really remove deleted hooks now */ - list = hook_list; - while (list) + depth--; + if (!depth) { - hook = list->data; - next = list->next; - if (!hook || hook->type == HOOK_DELETED) + /* really remove deleted hooks now */ + list = hook_list; + while (list) { - hook_list = g_slist_remove (hook_list, hook); - g_free (hook); + hook = list->data; + next = list->next; + if (!hook || hook->type == HOOK_DELETED) + { + hook_list = g_slist_remove (hook_list, hook); + g_free (hook); + } + list = next; } - list = next; } return eat; @@ -687,6 +694,18 @@ plugin_emit_print (session *sess, char *word[], time_t server_time) HOOK_PRINT | HOOK_PRINT_ATTRS); } +/* used by plugin_emit_dummy_print to fix some UB */ +static void +check_and_invalidate(void *plug_, void *killsess_) +{ + hexchat_plugin *plug = plug_; + session *killsess = killsess_; + if (plug->context == killsess) + { + plug->context = NULL; + } +} + int plugin_emit_dummy_print (session *sess, char *name) { @@ -697,7 +716,16 @@ plugin_emit_dummy_print (session *sess, char *name) for (i = 1; i < PDIWORDS; i++) word[i] = "\000"; - return plugin_hook_run (sess, name, word, NULL, NULL, HOOK_PRINT); + i = plugin_hook_run (sess, name, word, NULL, NULL, HOOK_PRINT); + + /* shoehorned fix for Undefined Behaviour */ + /* see https://stackoverflow.com/q/52628773/3691554 */ + /* this needs to be done on the hexchat side */ + if (strcmp(name, "Close Context") == 0) { + g_slist_foreach(plugin_list, &check_and_invalidate, sess); + } + + return i; } int |