From 847f2baf24691bf2229632d001374da15b56b995 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Fri, 29 Jul 2016 20:56:21 +0100 Subject: [PATCH] Fix a null pointer dereference. It sometimes happened when user attaches to a channel. No released version is affected. Thanks to Zoddo for the report! --- src/Chan.cpp | 2 +- test/integration/main.cpp | 72 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/src/Chan.cpp b/src/Chan.cpp index 9fb4ce72..8f7e910a 100644 --- a/src/Chan.cpp +++ b/src/Chan.cpp @@ -656,7 +656,7 @@ void CChan::SendBuffer(CClient* pClient, const CBuffer& Buffer) { BufLine.ToMessage(*pUseClient, MCString::EmptyMap); Message.SetChan(this); Message.SetNetwork(m_pNetwork); - Message.SetClient(pClient); + Message.SetClient(pUseClient); if (bBatch) { Message.SetTag("batch", sBatchName); } diff --git a/test/integration/main.cpp b/test/integration/main.cpp index a31711b2..e799f53e 100644 --- a/test/integration/main.cpp +++ b/test/integration/main.cpp @@ -303,6 +303,32 @@ class ZNCTest : public testing::Test { return std::unique_ptr(reply); } + void InstallModule(QString name, QString content) { + QDir dir(m_dir.path()); + ASSERT_TRUE(dir.mkpath("modules")); + ASSERT_TRUE(dir.cd("modules")); + if (name.endsWith(".cpp")) { + QTemporaryDir srcdir; + QFile file(QDir(srcdir.path()).filePath(name)); + ASSERT_TRUE(file.open(QIODevice::WriteOnly | QIODevice::Text)); + QTextStream out(&file); + out << content; + file.close(); + Process p( + ZNC_BIN_DIR "/znc-buildmod", QStringList() << file.fileName(), + [&](QProcess* proc) { + proc->setWorkingDirectory(dir.absolutePath()); + proc->setProcessChannelMode(QProcess::ForwardedChannels); + }); + p.ShouldFinishItself(); + } else { + QFile file(dir.filePath(name)); + ASSERT_TRUE(file.open(QIODevice::WriteOnly | QIODevice::Text)); + QTextStream out(&file); + out << content; + } + } + App m_app; QNetworkAccessManager m_network; QTemporaryDir m_dir; @@ -1849,4 +1875,50 @@ TEST_F(ZNCTest, BuildMod) { Z; } +TEST_F(ZNCTest, AutoAttachModule) { + auto znc = Run(); + Z; + auto ircd = ConnectIRCd(); + Z; + auto client = LoginClient(); + Z; + InstallModule("testmod.cpp", R"( + #include + #include + class TestModule : public CModule { + public: + MODCONSTRUCTOR(TestModule) {} + EModRet OnChanBufferPlayMessage(CMessage& Message) override { + PutIRC("TEST " + Message.GetClient()->GetNickMask()); + return CONTINUE; + } + }; + MODULEDEFS(TestModule, "Test") + )"); + Z; + client.Write("znc loadmod testmod"); + client.Write("PRIVMSG *controlpanel :Set AutoClearChanBuffer $me no"); + client.Write("PRIVMSG *simple_away :DisableTimer"); + client.Write("znc loadmod autoattach"); + client.Write("PRIVMSG *autoattach :Add * * *"); + client.ReadUntil("Added to list"); + Z; + ircd.Write(":server 001 nick :Hello"); + ircd.Write(":nick JOIN :#znc"); + ircd.Write(":server 353 nick #znc :nick"); + ircd.Write(":server 366 nick #znc :End of /NAMES list"); + ircd.Write(":foo PRIVMSG #znc :hi"); + client.ReadUntil(":foo PRIVMSG"); + client.Write("znc listchans"); + Z; + client.Write("detach #znc"); + client.ReadUntil("Detached"); + Z; + ircd.Write(":foo PRIVMSG #znc :hello"); + ircd.ReadUntil("TEST"); + Z; + client.ReadUntil("hello"); + Z; +} + } // namespace