diff --git a/include/znc/Message.h b/include/znc/Message.h index 0c0f2a08..3167a304 100644 --- a/include/znc/Message.h +++ b/include/znc/Message.h @@ -114,6 +114,7 @@ private: CClient* m_pClient = nullptr; CChan* m_pChan = nullptr; Type m_eType = Type::Unknown; + bool m_bColon = false; }; class CTargetMessage : public CMessage { diff --git a/src/Message.cpp b/src/Message.cpp index 66cd8332..e02d28ce 100644 --- a/src/Message.cpp +++ b/src/Message.cpp @@ -54,7 +54,7 @@ CString CMessage::GetParams(unsigned int uIdx, unsigned int uLen) const unsigned uParams = m_vsParams.size(); for (unsigned int i = uIdx; i < uIdx + uLen; ++i) { CString sParam = m_vsParams[i]; - if (i == uParams - 1 && (sParam.empty() || sParam.StartsWith(":") || sParam.Contains(" "))) { + if (i == uParams - 1 && (m_bColon || sParam.empty() || sParam.StartsWith(":") || sParam.Contains(" "))) { sParam = ":" + sParam; } vsParams.push_back(sParam); @@ -130,7 +130,7 @@ CString CMessage::ToString(unsigned int uFlags) const for (unsigned int uIdx = 0; uIdx < uParams; ++uIdx) { const CString& sParam = m_vsParams[uIdx]; sMessage += " "; - if (uIdx == uParams - 1 && (sParam.empty() || sParam.StartsWith(":") || sParam.Contains(" "))) { + if (uIdx == uParams - 1 && (m_bColon || sParam.empty() || sParam.StartsWith(":") || sParam.Contains(" "))) { sMessage += ":"; } sMessage += sParam; @@ -173,9 +173,11 @@ void CMessage::Parse(CString sMessage) sMessage = sMessage.Token(1, true); // + m_bColon = false; m_vsParams.clear(); while (!sMessage.empty()) { - if (sMessage.TrimPrefix(":")) { + m_bColon = sMessage.TrimPrefix(":"); + if (m_bColon) { m_vsParams.push_back(sMessage); sMessage.clear(); } else { diff --git a/test/MessageTest.cpp b/test/MessageTest.cpp index 647ce238..46e1bfe4 100644 --- a/test/MessageTest.cpp +++ b/test/MessageTest.cpp @@ -89,6 +89,10 @@ TEST(MessageTest, ToString) { EXPECT_EQ(":irc.znc.in CMD p1 p2", CMessage(CNick(":irc.znc.in"), "CMD", {"p1", "p2"}).ToString()); EXPECT_EQ(":irc.znc.in CMD :p p p", CMessage(CNick(":irc.znc.in"), "CMD", {"p p p"}).ToString()); EXPECT_EQ(":irc.znc.in CMD :", CMessage(CNick(":irc.znc.in"), "CMD", {""}).ToString()); + + // #1045 - retain the colon if it was there + EXPECT_EQ(":services. 328 user #chan http://znc.in", CMessage(":services. 328 user #chan http://znc.in").ToString()); + EXPECT_EQ(":services. 328 user #chan :http://znc.in", CMessage(":services. 328 user #chan :http://znc.in").ToString()); } TEST(MessageTest, FormatFlags) { @@ -222,7 +226,7 @@ TEST(MessageTest, Kick) { EXPECT_EQ("noone", msg.GetKickedNick()); msg.SetReason("test"); EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick KICK #chan noone test", msg.ToString()); + EXPECT_EQ(":nick KICK #chan noone :test", msg.ToString()); } TEST(MessageTest, Join) { @@ -283,7 +287,7 @@ TEST(MessageTest, Part) { msg.SetReason("test"); EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick PART #chan test", msg.ToString()); + EXPECT_EQ(":nick PART #chan :test", msg.ToString()); } TEST(MessageTest, PrivAction) { @@ -339,7 +343,7 @@ TEST(MessageTest, Quit) { msg.SetReason("test"); EXPECT_EQ("test", msg.GetReason()); - EXPECT_EQ(":nick QUIT test", msg.ToString()); + EXPECT_EQ(":nick QUIT :test", msg.ToString()); } TEST(MessageTest, Topic) { @@ -353,7 +357,7 @@ TEST(MessageTest, Topic) { msg.SetTopic("test"); EXPECT_EQ("test", msg.GetTopic()); - EXPECT_EQ(":nick TOPIC #chan test", msg.ToString()); + EXPECT_EQ(":nick TOPIC #chan :test", msg.ToString()); } TEST(MessageTest, Parse) {