summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/common/hexchat.c2
-rw-r--r--src/common/plugin.c48
2 files changed, 39 insertions, 11 deletions
diff --git a/src/common/hexchat.c b/src/common/hexchat.c
index 8702c63d..9be2e56d 100644
--- a/src/common/hexchat.c
+++ b/src/common/hexchat.c
@@ -191,7 +191,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