Resolves: rhbz#1261421 crash on mashing hangul korean keyboard

This commit is contained in:
Caolán McNamara 2015-09-11 13:43:32 +01:00
parent e7a4cb5499
commit fa17adea9e
2 changed files with 197 additions and 1 deletions

View File

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

View File

@ -3,7 +3,7 @@
Name: hunspell
Summary: A spell checker and morphological analyzer library
Version: 1.3.3
Release: 7%{?dist}
Release: 8%{?dist}
Source: http://downloads.sourceforge.net/%{name}/hunspell-%{version}.tar.gz
Group: System Environment/Libraries
URL: http://hunspell.sourceforge.net/
@ -18,6 +18,7 @@ BuildRequires: words
%endif
Requires: hunspell-en-US
Patch1: hunspell.rhbz915448.patch
Patch2: 0001-Resolves-rhbz-1261421-crash-on-mashing-hangul-korean.patch
%description
Hunspell is a spell checker and morphological analyzer library and program
@ -36,6 +37,7 @@ Includes and definitions for developing with hunspell
%prep
%setup -q
%patch1 -p0 -b .rhbz915448
%patch2 -p1 -b .rhbz1261421
%build
configureflags="--disable-rpath --disable-static --with-ui --with-readline"
@ -122,6 +124,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man5/hunspell.5.gz
%changelog
* Fri Sep 11 2015 Caolán McNamara <caolanm@redhat.com> - 1.3.3-8
- Resolves: rhbz#1261421 crash on mashing hangul korean keyboard
* Tue Jul 07 2015 Caolán McNamara <caolanm@redhat.com> - 1.3.3-7
- Resolves: rhbz#1239570 FTBFS in rawhide with valgrind warnings