Package: zhcon Version: 1:0.2.6-10 Severity: important Tags: patch pending -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256
When zhcon is running on a 64-bit system (e.g. amd64), after the end user has pressed Ctrl-Space to switch on the default (built-in) Chinese input method, pressing any alphabet to try to enter a Chinese character would immediately crash zhcon. This problem was also reported by users on various Ubuntu forums, e.g.: zhcon在64位下启动输入法崩溃 http://forum.ubuntu.org.cn/viewtopic.php?t=124062 A solution was posted in 2012: Ubuntu Server 12.04 64位系统编译安装zhcon 0.2.6 http://rsljdkt.iteye.com/blog/1670508 The original fix comes from an admin known as Md85 on the LinuxDev board on the Chinese SMTH BBS, to which he posted his patch on 2008-10-11, accessible through this URL: http://www.newsmth.net/nForum/#!article/LinuxDev/29280 His post is reproduced below: ============================================================================== 发信人: Md82 (我是KCN的一条狗啊), 信区: LinuxDev 标 题: 一上午时间终于把zhcon的输入法在x86-64调通 发信站: 水木社区 (Sat Oct 11 09:36:29 2008), 站内 zhcon0.2.6的输入法不能在 x86-64上运行,一输入字符就报告段错误 fedora9和fedora10打包的两个binary rpm也一样的问题 阅读代码后发现原作者假设所有机器都是32位指针,所以直接把码表文件(每单元4bytes) 映射到char**数组。在x86-64中,一个char*占了8字节,结果变成由两个码表的偏移量数 值错位32后或出来,明显会超界。 解决办法是把几个数组从char**改成int *,以及修改了相关的偏移量计算代码。现在终 于可以在console灌水了。 具体修改的文件是src/winime.cpp和src/winime.h。 - -- 自由对于笨人是极端痛苦的事情,不亚于把他们投入真空。 对于聪明人则不然。 ※ 修改:·Md82 于 Oct 11 09:38:01 2008 修改本文·[FROM: 115.130.13.*] ※ 来源:·水木社区 http://newsmth.net·[FROM: 115.130.13.*] 附件(8.7KB) winime.cpp (http://att.newsmth.net/nForum/att/LinuxDev/29280/839) 附件(2.8KB) winime.h (http://att.newsmth.net/nForum/att/LinuxDev/29280/9818) ============================================================================== I am happy to report that his patch works perfectly on my laptop running Debian sid (amd64/x86_64), and will upload a new version soon. Cheers, Anthony - -- System Information: Debian Release: stretch/sid APT prefers unstable APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental') Architecture: amd64 (x86_64) Foreign Architectures: i386 Kernel: Linux 4.2.0-1-amd64 (SMP w/4 CPU cores) Locale: LANG=en_CA.UTF-8, LC_CTYPE=en_CA.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages zhcon depends on: ii libc6 2.19-22 ii libgcc1 1:5.2.1-23 ii libgpm2 1.20.4-6.1+b2 ii libncurses5 6.0+20151024-2 ii libpth20 2.0.7-20 ii libstdc++6 5.2.1-23 ii libtinfo5 6.0+20151024-2 ii unicon-imc2 3.0.4-14+b1 zhcon recommends no packages. zhcon suggests no packages. - -- no debconf information -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAEBCAAGBQJWTanaAAoJEOolALQSxZrP7cwP+wSweFRvUAaayK6xVYFCiPFz LT+6hz5FilKOgeFqge7J3uGutPXBD6HLPhtrkUNCwmmyTYGtpaaO8D1PzLL02txH zrz9iY0yACh9lgMSM+ZqSC1hGkBzfCVtoZcqzw5c8Ygy4l8VKFgRUF1gfxqBbjbY 1rYWC35VlHD4HPY+MtsKcDf+3LaXmq2/BkRaPGFdyU94e3YvKyX15pn3wOIIF9LV jPVTXln7jUMtWYVgMBPyY66bOzCnqRkq9NKlb0GWXh7iEeDYXJdj3HqNlU5pqbIP C7kfdkq1jKNkk0kpbdyS8NvgwkaCfE0HHabl9MrYYZI0iJOkdTGVqGLXbnjWjvnN VKQYg0RrtbQUkUbgVwXxOMl8o2szC4kp9uKTJDpWKjqz3/9qhnOLHcHnndcQ2Up7 Loi2I8mJyQvuSG1WJfJn89HxjOI/8N4Bs2LE4IAEjWyD16m/xbLbIu5AqFhR+tr0 APLUCmARKk9/JTkmOfe5HFdX9Oh+XUNvpAkochPu7EQ5fgKnmubH2zvJxwGqob88 7RKlEYd8etmWEYC95zMkMLYFCOUlsAXFnTDaxwjIIt8e2g8gAzaKiFBuAEIPeAWq WgYN/MW2kNvXU//NViPYGtsf7cmiHR4Qf8NAO57KYpmpVFn/EO7kI7P8zEklWrDd XLd0/49BCs9gXg0bvkjW =hEEc -----END PGP SIGNATURE-----
--- a/src/winime.cpp +++ b/src/winime.cpp @@ -56,10 +56,10 @@ memcpy(&mHead, mpBuf, sizeof(mHead)); int len = strlen(mHead.mCodeSet); - mpIndex1 = (char **) (mpBuf + sizeof(mHead)); - mpIndex2 = (char **) (mpBuf + sizeof(mHead) + len * sizeof(char *)); - mpText = mpBuf + sizeof(mHead) + len * sizeof(char *) + - len * len * sizeof(char *); + mpIndex1 = (int *) (mpBuf + sizeof(mHead)); + mpIndex2 = (int *) (mpBuf + sizeof(mHead) + len * sizeof(int)); + mpText = mpBuf + sizeof(mHead) + len * sizeof(int) + + len * len * sizeof(int); } WinIme::~WinIme() { @@ -74,7 +74,7 @@ return false; } //add a word to candilist then push rp forward -void WinIme::AddCandilist(char *&rp,unsigned long& buflen) { +void WinIme::AddCandilist(char *&rp,unsigned int& buflen) { assert(mpList->mCount < 10); assert(!IsHzCode1(*rp)); //*rp is last matched latter @@ -163,7 +163,7 @@ count--; break; } - AddCandilist(t,(unsigned long&)buflen); + AddCandilist(t,(unsigned int&)buflen); } //search next word else { if (len == 1) //special for first char @@ -231,6 +231,9 @@ char *p = NULL; bool found = true; mInput[mNum] = c; + + + if (mNum == 0) { //1st level index //maybe prevent wildchar in 1st index is a good ideal @@ -246,7 +249,9 @@ // p = *t; } else - p = mpIndex1[Index(c)]; + { + p = (char *)mpIndex1[Index(c)]; + } if (p == (char *) 0xffffffff) found = false; @@ -257,20 +262,24 @@ if (c == mHead.mWildChar) { char **t; t = - find_if(mpIndex2 + Index(mInput[0]) * l, - mpIndex2 + (Index(mInput[0]) + 1) * l, + find_if((char **)(mpIndex2 + Index(mInput[0]) * l), + (char **)(mpIndex2 + (Index(mInput[0]) + 1) * l), bind2nd(not_equal_to < char *>(), (char *) 0xffffffff)); - if (t == mpIndex2 + (Index(mInput[0]) + 1) * l) + if (t == ((char **)mpIndex2) + (Index(mInput[0]) + 1) * l) + { p = (char *) 0xffffffff; + } else p = *t; } else - p = mpIndex2[Index(mInput[0]) * l + Index(c)]; + { + int dd = Index(mInput[0]) * l + Index(c); + p = (char *)(mpIndex2[Index(mInput[0]) * l + Index(c)]); + } if (p == (char *) 0xffffffff) found = false; - p = (unsigned long) p + mpText; } else if (mNum < mHead.mMaxCodes) { p = mpOffset[mNum - 1]; --- a/src/winime.h +++ b/src/winime.h @@ -45,7 +45,7 @@ string GetName(); bool InCodeSet(char c) const; int Search(string& s, int start); - void SetCandilist(Candilist* p,unsigned long len = 1000) { + void SetCandilist(Candilist* p,unsigned len = 1000) { mpList = p; mCandilistBufLen = len; } @@ -69,7 +69,7 @@ return c >= 0xA1 && c <= 0xFE; } - void AddCandilist(char*& p,unsigned long& buflen); + void AddCandilist(char*& p,unsigned& buflen); void SkipNext(char*& rp); int MatchWord(char* p, int len, int offset); bool IsGB2312(char* p); @@ -80,15 +80,15 @@ char mInput[12 + 1]; bool mGBKOut; Candilist* mpList; - char* mpOffset[12]; + char * mpOffset[12]; int mFd; char* mpBuf; - char** mpIndex1; - char** mpIndex2; + int *mpIndex1; + int *mpIndex2; char* mpText; char* mpCur; //current search position - unsigned long mBufSize; - unsigned long mCandilistBufLen; + unsigned int mBufSize; + unsigned int mCandilistBufLen; WinImeHead mHead; }; #endif