fa17ade
From 97e079a23d459aeb6e64435350d7710c90dbca85 Mon Sep 17 00:00:00 2001
fa17ade
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
fa17ade
Date: Fri, 11 Sep 2015 13:28:52 +0100
fa17ade
Subject: [PATCH] Resolves: rhbz#1261421 crash on mashing hangul korean
fa17ade
 keyboard
fa17ade
fa17ade
---
fa17ade
 src/hunspell/hunspell.cxx | 69 +++++++++++++++++++++++++++++++++++------------
fa17ade
 src/hunspell/hunspell.hxx |  4 ++-
fa17ade
 src/hunspell/replist.cxx  | 18 ++++++++++---
fa17ade
 src/hunspell/replist.hxx  |  2 ++
fa17ade
 src/tools/hunspell.cxx    |  2 +-
fa17ade
 6 files changed, 78 insertions(+), 24 deletions(-)
fa17ade
fa17ade
diff --git a/src/hunspell/hunspell.cxx b/src/hunspell/hunspell.cxx
fa17ade
index 7fae54b..d8ef357 100644
fa17ade
--- a/src/hunspell/hunspell.cxx
fa17ade
+++ b/src/hunspell/hunspell.cxx
fa17ade
@@ -12,6 +12,7 @@
fa17ade
 #endif
fa17ade
 #include "csutil.hxx"
fa17ade
 
fa17ade
+#include <limits>
fa17ade
 #include <string>
fa17ade
 
fa17ade
 Hunspell::Hunspell(const char * affpath, const char * dpath, const char * key)
fa17ade
@@ -349,8 +350,13 @@ int Hunspell::spell(const char * word, int * info, char ** root)
fa17ade
 
fa17ade
   // input conversion
fa17ade
   RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
fa17ade
-  if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
-  else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
+  int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
fa17ade
+  if (convstatus < 0)
fa17ade
+    return 0;
fa17ade
+  else if (convstatus > 0)
fa17ade
+    wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
+  else
fa17ade
+    wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
 
fa17ade
   if (wl == 0 || maxdic == 0) return 1;
fa17ade
   if (root) *root = NULL;
fa17ade
@@ -702,8 +708,13 @@ int Hunspell::suggest(char*** slst, const char * word)
fa17ade
 
fa17ade
   // input conversion
fa17ade
   RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
fa17ade
-  if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
-  else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
+  int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
fa17ade
+  if (convstatus < 0)
fa17ade
+    return 0;
fa17ade
+  else if (convstatus > 0)
fa17ade
+    wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
+  else
fa17ade
+    wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
 
fa17ade
   if (wl == 0) return 0;
fa17ade
   int ns = 0;
fa17ade
@@ -1020,7 +1031,7 @@ int Hunspell::suggest(char*** slst, const char * word)
fa17ade
   // output conversion
fa17ade
   rl = (pAMgr) ? pAMgr->get_oconvtable() : NULL;
fa17ade
   for (int j = 0; rl && j < ns; j++) {
fa17ade
-    if (rl->conv((*slst)[j], wspace)) {
fa17ade
+    if (rl->conv((*slst)[j], wspace, MAXWORDUTF8LEN) > 0) {
fa17ade
       free((*slst)[j]);
fa17ade
       (*slst)[j] = mystrdup(wspace);
fa17ade
     }
fa17ade
@@ -1395,8 +1406,13 @@ int Hunspell::analyze(char*** slst, const char * word)
fa17ade
 
fa17ade
   // input conversion
fa17ade
   RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
fa17ade
-  if (rl && rl->conv(word, wspace)) wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
-  else wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
+  int convstatus = rl ? rl->conv(word, wspace, MAXWORDUTF8LEN) : 0;
fa17ade
+  if (convstatus < 0)
fa17ade
+    return 0;
fa17ade
+  else if (convstatus > 0)
fa17ade
+    wl = cleanword2(cw, wspace, unicw, &nc, &captype, &abbv);
fa17ade
+  else
fa17ade
+    wl = cleanword2(cw, word, unicw, &nc, &captype, &abbv);
fa17ade
 
fa17ade
   if (wl == 0) {
fa17ade
       if (abbv) {
fa17ade
@@ -1684,12 +1700,16 @@ int Hunspell::get_langnum() const
fa17ade
    return langnum;
fa17ade
 }
fa17ade
 
fa17ade
-int Hunspell::input_conv(const char * word, char * dest)
fa17ade
+int Hunspell::input_conv(const char * word, char * dest, size_t destsize)
fa17ade
 {
fa17ade
   RepList * rl = (pAMgr) ? pAMgr->get_iconvtable() : NULL;
fa17ade
-  return (rl && rl->conv(word, dest));
fa17ade
+  return (rl && rl->conv(word, dest, destsize) > 0);
fa17ade
 }
fa17ade
 
fa17ade
+int Hunspell::input_conv(const char * word, char * dest)
fa17ade
+{
fa17ade
+  return input_conv(word, dest, std::numeric_limits<std::size_t>::max());
fa17ade
+}
fa17ade
 
fa17ade
 // return the beginning of the element (attr == NULL) or the attribute
fa17ade
 const char * Hunspell::get_xml_pos(const char * s, const char * attr)
fa17ade
diff --git a/src/hunspell/hunspell.hxx b/src/hunspell/hunspell.hxx
fa17ade
index e62f0dd..0b5ad2e 100644
fa17ade
--- a/src/hunspell/hunspell.hxx
fa17ade
+++ b/src/hunspell/hunspell.hxx
fa17ade
@@ -226,7 +226,9 @@ public:
fa17ade
 
fa17ade
   /* need for putdic */
fa17ade
   int input_conv(const char * word, char * dest);
fa17ade
-  
fa17ade
+  // ^^-deprecated, use this-vv"
fa17ade
+  int input_conv(const char * word, char * dest, size_t destsize);
fa17ade
+ 
fa17ade
   /* experimental and deprecated functions */
fa17ade
 
fa17ade
 #ifdef HUNSPELL_EXPERIMENTAL
fa17ade
diff --git a/src/hunspell/replist.cxx b/src/hunspell/replist.cxx
fa17ade
index b9b1255..bac3e06 100644
fa17ade
--- a/src/hunspell/replist.cxx
fa17ade
+++ b/src/hunspell/replist.cxx
fa17ade
@@ -74,6 +74,7 @@
fa17ade
 #include <stdlib.h>
fa17ade
 #include <string.h>
fa17ade
 #include <stdio.h>
fa17ade
+#include <limits>
fa17ade
 
fa17ade
 #include "replist.hxx"
fa17ade
 #include "csutil.hxx"
fa17ade
@@ -139,19 +140,30 @@ int RepList::add(char * pat1, char * pat2) {
fa17ade
     return 0;
fa17ade
 }
fa17ade
 
fa17ade
-int RepList::conv(const char * word, char * dest) {
fa17ade
+int RepList::conv(const char * word, char * dest, size_t destsize) {
fa17ade
     int stl = 0;
fa17ade
     int change = 0;
fa17ade
     for (size_t i = 0; i < strlen(word); i++) {
fa17ade
         int n = near(word + i);
fa17ade
         int l = match(word + i, n);
fa17ade
         if (l) {
fa17ade
+          size_t replen = strlen(dat[n]->pattern2);
fa17ade
+          if (stl+replen >= destsize)
fa17ade
+            return -1;
fa17ade
           strcpy(dest + stl, dat[n]->pattern2);
fa17ade
-          stl += strlen(dat[n]->pattern2);
fa17ade
+          stl += replen;
fa17ade
           i += l - 1;
fa17ade
           change = 1;
fa17ade
-        } else dest[stl++] = word[i];
fa17ade
+        } else {
fa17ade
+          if (stl+1 >= destsize)
fa17ade
+            return -1;
fa17ade
+          dest[stl++] = word[i];
fa17ade
+        }
fa17ade
     }
fa17ade
     dest[stl] = '\0';
fa17ade
     return change;
fa17ade
 }
fa17ade
+
fa17ade
+int RepList::conv(const char * word, char * dest) {
fa17ade
+    return conv(word, dest, std::numeric_limits<std::size_t>::max());
fa17ade
+}
fa17ade
diff --git a/src/hunspell/replist.hxx b/src/hunspell/replist.hxx
fa17ade
index 1e3d6e4..e418298 100644
fa17ade
--- a/src/hunspell/replist.hxx
fa17ade
+++ b/src/hunspell/replist.hxx
fa17ade
@@ -99,5 +99,7 @@ public:
fa17ade
     int near(const char * word);
fa17ade
     int match(const char * word, int n);
fa17ade
     int conv(const char * word, char * dest);
fa17ade
+    // ^^-deprecated, use this-vv"
fa17ade
+    int conv(const char * word, char * dest, size_t destsize);
fa17ade
 };
fa17ade
 #endif
fa17ade
diff --git a/src/tools/hunspell.cxx b/src/tools/hunspell.cxx
fa17ade
index 6124ac4..1b50fe1 100644
fa17ade
--- a/src/tools/hunspell.cxx
fa17ade
+++ b/src/tools/hunspell.cxx
fa17ade
@@ -524,7 +524,7 @@ int putdic(char * word, Hunspell * pMS)
fa17ade
     
fa17ade
     word = chenc(word, ui_enc, dic_enc[0]);
fa17ade
 
fa17ade
-    if(pMS->input_conv(word, buf)) word = buf;
fa17ade
+    if(pMS->input_conv(word, buf, MAXLNLEN)) word = buf;
fa17ade
     
fa17ade
     int ret;
fa17ade
     
fa17ade
-- 
fa17ade
2.4.0
fa17ade