diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index ec4edfd2..39dce871 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -550,10 +550,6 @@ bool CIRCSock::OnChgHostMessage(CChgHostMessage& Message) { if (pChan->IsDisabled()) continue; if (pChan->IsDetached()) continue; - CTargetMessage ModeMsg; - ModeMsg.SetNick(CNick(":irc.znc.in")); - ModeMsg.SetTags(Message.GetTags()); - ModeMsg.SetCommand("MODE"); VCString vsModeParams = {pChan->GetName(), "+"}; if (CNick* pNick = pChan->FindNick(NewNick.GetNick())) { for (char cPerm : pNick->GetPermStr()) { @@ -563,7 +559,13 @@ bool CIRCSock::OnChgHostMessage(CChgHostMessage& Message) { vsModeParams.push_back(NewNick.GetNick()); } } + } else { + continue; } + CTargetMessage ModeMsg; + ModeMsg.SetNick(CNick(":irc.znc.in")); + ModeMsg.SetTags(Message.GetTags()); + ModeMsg.SetCommand("MODE"); ModeMsg.SetParams(std::move(vsModeParams)); for (CClient* pClient : m_pNetwork->GetClients()) { diff --git a/test/integration/tests/core.cpp b/test/integration/tests/core.cpp index d9364924..470de11d 100644 --- a/test/integration/tests/core.cpp +++ b/test/integration/tests/core.cpp @@ -805,5 +805,28 @@ TEST_F(ZNCTest, ChgHostOnce) { Not(HasSubstr("CHGHOST"))); } +TEST_F(ZNCTest, ChgHostOnlyNicksAlreadyOnChannels) { + auto znc = Run(); + auto ircd = ConnectIRCd(); + ircd.Write("CAP user LS :chghost"); + ircd.ReadUntil("CAP REQ :chghost"); + ircd.Write("CAP user ACK :chghost"); + + auto client = LoginClient(); + ircd.Write(":user!ident@host JOIN #chan1"); + ircd.Write(":user!ident@host JOIN #chan2"); + ircd.Write(":another!ident@host JOIN #chan1"); + client.ReadUntil("another"); + + ircd.Write(":another!ident@host CHGHOST i2 h2"); + client.ReadUntil(":another!i2@h2 JOIN #chan1"); + + // Can't combine into previous channels could arrive in random order, which + // messes with ReadUntil assertions. + ircd.Write(":another!i2@h2 CHGHOST i3 h3"); + ASSERT_THAT(client.ReadRemainder().toStdString(), + Not(HasSubstr("#chan2"))); +} + } // namespace } // namespace znc_inttest