From a3b3ef1417e9698b02c60cb3ef3e0ec018d667bd Mon Sep 17 00:00:00 2001 From: wangcong Date: Tue, 31 Oct 2023 11:10:34 +0800 Subject: [PATCH] fix: Roll back gb18030 midification MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Description: iconv底层适配GB18030-2022标准,回退上层应用GB18030修改。当处于2005标准时 仍会强制使用上层修改补丁以适配2022标准。 Log: Roll back gb18030 midification --- 3rdparty/terminalwidget/lib/Emulation.cpp | 44 ++++++++++++++++++++++- 3rdparty/terminalwidget/lib/Emulation.h | 8 +++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/3rdparty/terminalwidget/lib/Emulation.cpp b/3rdparty/terminalwidget/lib/Emulation.cpp index 9601f2396..827a13e7e 100644 --- a/3rdparty/terminalwidget/lib/Emulation.cpp +++ b/3rdparty/terminalwidget/lib/Emulation.cpp @@ -298,6 +298,44 @@ void Emulation::sendMouseEvent(int /*buttons*/, int /*column*/, int /*row*/, int // default implementation does nothing } +static int isUse2005Standard = -1; +/** + @brief 检测当前iconv使用的GB18030编码是否为2005标准,2005标准强制使用上层补丁版本 + 通过检测2005和2022编码转的差异,以附录D中的编码为例验证 + 2005标准 0xFE51 --> \u20087 + 2022标准 0xFE51 --> \uE816 + @return iconv使用GB18030编码是否为2005标准,默认返回true + */ +bool Emulation::detectIconvUse2005Standard() +{ + iconv_t handle = iconv_open("UTF-8", "GB18030"); + if (handle == reinterpret_cast(-1)) { + return true; + } + + QByteArray input("\xFE\x51"); + QByteArray output(input.size() * 2, 0); + char *inputData = input.data(); + char *outputData = output.data(); + size_t inputLen = static_cast(input.count()); + size_t outputLen = static_cast(output.count()); + + const size_t ret = iconv(handle, &inputData, &inputLen, &outputData, &outputLen); + iconv_close(handle); + + if (ret == static_cast(-1)) { + return true; + } + + if (!output.contains("\uE816")) { + qInfo() << "Current iconv gb18030 standard is 2005."; + return true; + } + + qInfo() << "Current iconv gb18030 standard is 2022."; + return false; +} + /* We are doing code conversion from locale to unicode first. TODO: Character composition from the old code. See #96536 @@ -338,7 +376,11 @@ void Emulation::receiveData(const char *text, int length, bool isCommandExec) //setIsCodecGB18030(false); } else { - if(_codec->name().toUpper().contains("GB18030")) { + if(isUse2005Standard == -1){ + isUse2005Standard = detectIconvUse2005Standard(); + qInfo() << "Is Used 2005 standard's gb18030 iconv?" << isUse2005Standard; + } + if(_codec->name().toUpper().contains("GB18030") && isUse2005Standard == 1) { //setIsCodecGB18030(true); QByteArray gbkarr(text, length); QByteArray Outdata; diff --git a/3rdparty/terminalwidget/lib/Emulation.h b/3rdparty/terminalwidget/lib/Emulation.h index e4b533b75..7fab156e9 100644 --- a/3rdparty/terminalwidget/lib/Emulation.h +++ b/3rdparty/terminalwidget/lib/Emulation.h @@ -515,6 +515,14 @@ public slots: /*const */KeyboardTranslator *_keyTranslator; // the keyboard layout /********************* Modify by ut000610 daizhengwen End ************************/ + /** + @brief 检测当前iconv使用的GB18030编码是否为2005标准,2005标准强制使用上层补丁版本 + 通过检测2005和2022编码转的差异,以附录D中的编码为例验证 + 2005标准 0xFE51 --> \u20087 + 2022标准 0xFE51 --> \uE816 + @return iconv使用GB18030编码是否为2005标准,默认返回true + */ + bool detectIconvUse2005Standard(); protected slots: /** * Schedules an update of attached views.