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

Reply via email to