diff --git a/src/Chan.cpp b/src/Chan.cpp index 12c71fe3..88433a3e 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -143,7 +143,9 @@ void CChan::JoinUser(const CString& sKey) { if (!IsOn() && !sKey.empty()) { SetKey(sKey); } - m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); + if (m_pNetwork->IsIRCConnected()) { + m_pNetwork->PutIRC("JOIN " + GetName() + " " + GetKey()); + } } void CChan::AttachUser(CClient* pClient) { diff --git a/src/Client.cpp b/src/Client.cpp index fcc7fe2e..b3753e28 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1477,13 +1477,13 @@ bool CClient::OnJoinMessage(CJoinMessage& Message) { pChan->SetKey(sKey); } } - } - if (!sChannel.empty()) { - sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); + if (!sChannel.empty() && m_pNetwork->IsIRCConnected()) { + sChans += (sChans.empty()) ? sChannel : CString("," + sChannel); - if (!vsKeys.empty()) { - sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); + if (!vsKeys.empty()) { + sKeys += (sKeys.empty()) ? sKey : CString("," + sKey); + } } } } diff --git a/test/integration/tests/core.cpp b/test/integration/tests/core.cpp index 4d000dcb..0aa6c373 100644 --- a/test/integration/tests/core.cpp +++ b/test/integration/tests/core.cpp @@ -1172,5 +1172,19 @@ TEST_F(ZNCTest, ManyCapsInReq) { EXPECT_TRUE(caps.split(' ').contains(caps3)); } +TEST_F(ZNCTest, JoinWhileRegistration) { + auto znc = Run(); + auto ircd = ConnectIRCd(); + auto client = LoginClient(); + // First JOIN just adds channel to the list, second one updates the key and + // sends JOIN from CChan::JoinUser. Both should be delayed until + // registration ends. + client.Write("JOIN #foo"); + client.Write("JOIN #foo"); + EXPECT_THAT(ircd.ReadRemainder().toStdString(), Not(HasSubstr("JOIN"))); + ircd.Write(":server 001 nick :Hello"); + ircd.ReadUntil("JOIN #foo"); +} + } // namespace } // namespace znc_inttest