From 31005e18b14e8902252e7d4c20955dfaeb495d35 Mon Sep 17 00:00:00 2001 From: Bram Matthys Date: Fri, 13 Mar 2026 13:40:51 +0100 Subject: [PATCH] Fix extbans in +I not being converted to letter bans to older servers. This affects servers without NEXTBANS, such as anope 2.0.x series (anope 2.1.x is not affected as it supports NEXTBANS). Non-NEXTBANS servers only support letter extbans so we are supposed to convert ~security-group:known-users to ~G:known-users when sending to such a server, in unreal_server_compat. And we did this well for the MODE command for +beI. In SJOIN we did this correctly for +b/+e but not for +I due to a silly code mistake. This bug is present since 6.0.0 but wasn't noticed until now. To be a real problem you need something like: 1. Anope 2.0.x series (or other services without NEXTBANS) 2. A channel with +I extbans 3. KEEPMODES set on that channel Then what happens is when services boot: 1. UnrealIRCd will sync with anope 2.0.x and incorrectly send named bans, which will confuse anope. But nothing strange happens yet at this point. 2. Then on next server sync (eg anope restart or unreal restart) anope will try to restore these but they end up with weird entries like +I *!*@~security-group:known-users (note the *!*@ prefix) And it should be noted that this would also happen in a situation with UnrealIRCd 5 + UnrealIRCd 6 servers, but UnrealIRCd 5 is End Of Life anyway. Reported by BlackBishop and Sadie two days ago. Thanks! --- src/modules/unreal_server_compat.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/unreal_server_compat.c b/src/modules/unreal_server_compat.c index 1770bbbf7..00fed8f16 100644 --- a/src/modules/unreal_server_compat.c +++ b/src/modules/unreal_server_compat.c @@ -242,7 +242,7 @@ int usc_reparse_sjoin(char **msg, char *p, int *length) log_data_string("ban", s)); continue; } - if (!strchr("&\"\\", next[1])) + if (!strchr("&\"'", next[1])) goto fallback_usc_reparse_sjoin; *next++ = '\0'; result = clean_ban_mask(next+1, MODE_ADD, EXBTYPE_BAN, &me, NULL, 1); // some context lost @@ -259,7 +259,7 @@ int usc_reparse_sjoin(char **msg, char *p, int *length) strlcat(obuf, result, sizeof(obuf)); /* the converted result */ strlcat(obuf, " ", sizeof(obuf)); } else - if (strchr("&\"\\", *s)) + if (strchr("&\"'", *s)) { /* +b / +e / +I */ const char *result = clean_ban_mask(s+1, MODE_ADD, EXBTYPE_BAN, &me, NULL, 1); // some context lost