From 4fe4a45dd62411ba9ede04750ca44f071e7d6cbb Mon Sep 17 00:00:00 2001 From: Alexey Sokolov Date: Sat, 9 Jan 2016 14:09:34 +0000 Subject: [PATCH] Disable legacy encoding mode when modpython is loaded. Python is not happy when using non-unicode text as str. Fix #1229 --- configure.ac | 3 +++ include/znc/znc.h | 6 ++++++ modules/data/webadmin/tmpl/encoding_settings.tmpl | 9 +++++++-- modules/modpython.cpp | 2 ++ modules/webadmin.cpp | 6 ++++++ src/Client.cpp | 2 +- src/IRCSock.cpp | 2 +- src/znc.cpp | 11 +++++++++++ 8 files changed, 37 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index eec8c1a5..e69fd08c 100644 --- a/configure.ac +++ b/configure.ac @@ -584,6 +584,9 @@ if test "x$PYTHON" != "xno"; then LIBS="$my_saved_LIBS" CXXFLAGS="$my_saved_CXXFLAGS" fi + if test "x$HAVE_ICU" != "xyes"; then + AC_MSG_ERROR([Modpython requires ZNC to be compiled with charset support, but ICU library not found. Try --disable-python or install libicu.]) + fi if test "x$PYTHON" = "xno"; then ZNC_AUTO_FAIL([PYTHON], [python not found. Try --disable-python.], diff --git a/include/znc/znc.h b/include/znc/znc.h index cdb0a4b2..ca9d5f56 100644 --- a/include/znc/znc.h +++ b/include/znc/znc.h @@ -233,6 +233,11 @@ class CZNC { void PauseConnectQueue(); void ResumeConnectQueue(); + void ForceEncoding(); + void UnforceEncoding(); + bool IsForcingEncoding() const; + CString FixupEncoding(const CString& sEncoding) const; + // Never call this unless you are CConnectQueueTimer::~CConnectQueueTimer() void LeakConnectQueueTimer(CConnectQueueTimer* pTimer); @@ -289,6 +294,7 @@ class CZNC { std::list m_lpConnectQueue; CConnectQueueTimer* m_pConnectQueueTimer; unsigned int m_uiConnectPaused; + unsigned int m_uiForceEncoding; TCacheMap m_sConnectThrottle; bool m_bProtectWebSessions; bool m_bHideVersion; diff --git a/modules/data/webadmin/tmpl/encoding_settings.tmpl b/modules/data/webadmin/tmpl/encoding_settings.tmpl index 543ef6d1..d0d3e60b 100644 --- a/modules/data/webadmin/tmpl/encoding_settings.tmpl +++ b/modules/data/webadmin/tmpl/encoding_settings.tmpl @@ -3,10 +3,15 @@
ZNC is compiled without encodings support. ICU is required for it.
- + +
+ + Legacy mode is disabled by modpython. +
+
- checked="checked" disabled="disabled" /> + checked="checked" disabled="disabled" />
diff --git a/modules/modpython.cpp b/modules/modpython.cpp index 631a71ac..8df6ebc6 100644 --- a/modules/modpython.cpp +++ b/modules/modpython.cpp @@ -82,6 +82,7 @@ class CModPython : public CModule { } MODCONSTRUCTOR(CModPython) { + CZNC::Get().ForceEncoding(); Py_Initialize(); m_PyFormatException = nullptr; m_PyZNCModule = nullptr; @@ -386,6 +387,7 @@ class CModPython : public CModule { Py_CLEAR(m_PyFormatException); Py_CLEAR(m_PyZNCModule); Py_Finalize(); + CZNC::Get().UnforceEncoding(); } }; diff --git a/modules/webadmin.cpp b/modules/webadmin.cpp index 2ce7dd0e..32439b80 100644 --- a/modules/webadmin.cpp +++ b/modules/webadmin.cpp @@ -1013,7 +1013,10 @@ class CWebAdminMod : public CModule { Tmpl["EncodingUtf"] = "simple"; Tmpl["Encoding"] = sEncoding; } + Tmpl["LegacyEncodingDisabled"] = + CString(CZNC::Get().IsForcingEncoding()); #else + Tmpl["LegacyEncodingDisabled"] = "true"; Tmpl["EncodingDisabled"] = "true"; Tmpl["EncodingUtf"] = "legacy"; #endif @@ -1353,7 +1356,10 @@ class CWebAdminMod : public CModule { Tmpl["EncodingUtf"] = "simple"; Tmpl["Encoding"] = sEncoding; } + Tmpl["LegacyEncodingDisabled"] = + CString(CZNC::Get().IsForcingEncoding()); #else + Tmpl["LegacyEncodingDisabled"] = "true"; Tmpl["EncodingDisabled"] = "true"; Tmpl["EncodingUtf"] = "legacy"; #endif diff --git a/src/Client.cpp b/src/Client.cpp index 7f75cb64..1b49f4e2 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(m_pUser->GetClientEncoding()); + SetEncoding(CZNC::Get().FixupEncoding(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 eb6aa605..fea6f4a1 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(m_pNetwork->GetEncoding()); + SetEncoding(CZNC::Get().FixupEncoding((m_pNetwork->GetEncoding()))); m_mueChanModes['b'] = ListArg; m_mueChanModes['e'] = ListArg; diff --git a/src/znc.cpp b/src/znc.cpp index 616ec25b..ce732342 100644 --- a/src/znc.cpp +++ b/src/znc.cpp @@ -72,6 +72,7 @@ CZNC::CZNC() m_lpConnectQueue(), m_pConnectQueueTimer(nullptr), m_uiConnectPaused(0), + m_uiForceEncoding(0), m_sConnectThrottle(), m_bProtectWebSessions(true), m_bHideVersion(false) { @@ -2071,6 +2072,16 @@ void CZNC::ResumeConnectQueue() { } } +void CZNC::ForceEncoding() { m_uiForceEncoding++; } +void CZNC::UnforceEncoding() { m_uiForceEncoding--; } +bool CZNC::IsForcingEncoding() const { return m_uiForceEncoding; } +CString CZNC::FixupEncoding(const CString& sEncoding) const { + if (sEncoding.empty() && m_uiForceEncoding) { + return "UTF-8"; + } + return sEncoding; +} + void CZNC::AddNetworkToQueue(CIRCNetwork* pNetwork) { // Make sure we are not already in the queue if (std::find(m_lpConnectQueue.begin(), m_lpConnectQueue.end(), pNetwork) !=