From 1f226d2adeb2cfa08fa54d360c110c16fd361f18 Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 9 Jan 2016 18:00:47 +0000 Subject: [PATCH] Add test for #1229 and actually fix it. --- include/znc/Socket.h | 6 ++---- src/Client.cpp | 2 +- src/IRCSock.cpp | 2 +- src/Socket.cpp | 6 ++++++ src/znc.cpp | 9 ++++++++- test/Integration.cpp | 19 ++++++++++++------- third_party/Csocket | 2 +- 7 files changed, 31 insertions(+), 15 deletions(-) diff --git a/include/znc/Socket.h b/include/znc/Socket.h index f15b0901..9804d0a5 100644 --- a/include/znc/Socket.h +++ b/include/znc/Socket.h @@ -45,10 +45,8 @@ class CZNCSock : public Csock { m_ssTrustedFingerprints = ssFPs; } -#ifndef HAVE_ICU - // Don't fail to compile when ICU is not enabled - void SetEncoding(const CString&) {} -#endif + void SetEncoding(const CString&); + virtual CString GetRemoteIP() const { return Csock::GetRemoteIP(); } protected: diff --git a/src/Client.cpp b/src/Client.cpp index 1b49f4e2..7f75cb64 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -384,7 +384,7 @@ void CClient::AcceptLogin(CUser& User) { SetTimeout(CIRCNetwork::NO_TRAFFIC_TIMEOUT, TMO_READ); SetSockName("USR::" + m_pUser->GetUserName()); - SetEncoding(CZNC::Get().FixupEncoding(m_pUser->GetClientEncoding())); + SetEncoding(m_pUser->GetClientEncoding()); if (!m_sNetwork.empty()) { m_pNetwork = m_pUser->FindNetwork(m_sNetwork); diff --git a/src/IRCSock.cpp b/src/IRCSock.cpp index fea6f4a1..eb6aa605 100644 --- a/src/IRCSock.cpp +++ b/src/IRCSock.cpp @@ -91,7 +91,7 @@ CIRCSock::CIRCSock(CIRCNetwork* pNetwork) EnableReadLine(); m_Nick.SetIdent(m_pNetwork->GetIdent()); m_Nick.SetHost(m_pNetwork->GetBindHost()); - SetEncoding(CZNC::Get().FixupEncoding((m_pNetwork->GetEncoding()))); + SetEncoding(m_pNetwork->GetEncoding()); m_mueChanModes['b'] = ListArg; m_mueChanModes['e'] = ListArg; diff --git a/src/Socket.cpp b/src/Socket.cpp index ab9ffe13..8417b5d5 100644 --- a/src/Socket.cpp +++ b/src/Socket.cpp @@ -176,6 +176,12 @@ CString CZNCSock::GetSSLPeerFingerprint() const { #endif } +void CZNCSock::SetEncoding(const CString& sEncoding) { +#ifdef HAVE_ICU + Csock::SetEncoding(CZNC::Get().FixupEncoding(sEncoding)); +#endif +} + #ifdef HAVE_PTHREAD class CSockManager::CThreadMonitorFD : public CSMonitorFD { public: diff --git a/src/znc.cpp b/src/znc.cpp index ce732342..c01960c0 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -2072,7 +2072,14 @@ void CZNC::ResumeConnectQueue() { } } -void CZNC::ForceEncoding() { m_uiForceEncoding++; } +void CZNC::ForceEncoding() { + m_uiForceEncoding++; + for (Csock* pSock : GetManager()) { + if (pSock->GetEncoding().empty()) { + pSock->SetEncoding("UTF-8"); + } + } +} void CZNC::UnforceEncoding() { m_uiForceEncoding--; } bool CZNC::IsForcingEncoding() const { return m_uiForceEncoding; } CString CZNC::FixupEncoding(const CString& sEncoding) const { diff --git a/test/Integration.cpp b/test/Integration.cpp index cd0966e8..ca6eefd7 100644 --- a/test/Integration.cpp +++ b/test/Integration.cpp @@ -76,7 +76,7 @@ class IO { m_readed += chunk; } } - void Write(QString s = "", bool new_line = true) { + void Write(QByteArray s = "", bool new_line = true) { if (!m_device) return; if (m_verbose) { std::cout << s.toStdString() << std::flush; @@ -85,9 +85,10 @@ class IO { } } s += "\n"; - { - QTextStream str(m_device); - str << s; + while (!s.isEmpty()) { + auto res = m_device->write(s); + ASSERT_NE(res, -1); + s.remove(0, res); } FlushIfCan(m_device); } @@ -103,8 +104,7 @@ class IO { } private: - // QTextStream doesn't flush QTcpSocket, and QIODevice doesn't have flush() - // at all... + // Need to flush QTcpSocket, and QIODevice doesn't have flush at all... static void FlushIfCan(QIODevice*) {} static void FlushIfCan(QTcpSocket* sock) { sock->flush(); } @@ -469,7 +469,7 @@ TEST_F(ZNCTest, ControlpanelModule) { auto client = LoginClient(); Z; - const QString request = "PRIVMSG *controlpanel :"; + const QByteArray request = "PRIVMSG *controlpanel :"; const QByteArray response = ":*controlpanel!znc@znc.in PRIVMSG nick :"; // TODO: Figure out how to check for "HAVE_ICU" to test encoding. @@ -1766,6 +1766,11 @@ TEST_F(ZNCTest, Modpython) { client.Write("PRIVMSG *pyeval :module.GetUser().GetUserName()"); client.ReadUntil("nick :'user'"); Z; + ircd.Write(":server 001 nick :Hello"); + ircd.Write(":n!u@h PRIVMSG nick :Hi\xF0, github issue #1229"); + // "replacement character" + client.ReadUntil("Hi\xEF\xBF\xBD, github issue"); + Z; } } // namespace diff --git a/third_party/Csocket b/third_party/Csocket index 2852fc36..24ea8547 160000 --- a/third_party/Csocket +++ b/third_party/Csocket @@ -1 +1 @@ -Subproject commit 2852fc364542c0635058f90d8a3dbad0455e9e7c +Subproject commit 24ea8547f59b2e3dd34c47a47493235f914c0b22