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