bump hunspell to 1.3.4

Change-Id: If7c4868c4296d1ca0e485dc06fdf3472e2e8653f
Reviewed-on: https://gerrit.libreoffice.org/23863
Tested-by: Jenkins <ci@libreoffice.org>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
diff --git a/download.lst b/download.lst
index 23ec620..21c95b1 100644
--- a/download.lst
+++ b/download.lst
@@ -61,7 +61,7 @@ export GRAPHITE_TARBALL := 4311dd9ace498b57c85f611e0670df64-graphite2-minimal-1.
export HARFBUZZ_MD5SUM := 0e27e531f4c4acff601ebff0957755c2
export HARFBUZZ_TARBALL := harfbuzz-0.9.40.tar.bz2
export HSQLDB_TARBALL := 17410483b5b5f267aa18b7e00b65e6e0-hsqldb_1_8_0.zip
export HUNSPELL_TARBALL := 4967da60b23413604c9e563beacc63b4-hunspell-1.3.3.tar.gz
export HUNSPELL_TARBALL := 423cff69e68c87ac11e4aa8462951954-hunspell-1.3.4.tar.gz
export HYPHEN_TARBALL := 5ade6ae2a99bc1e9e57031ca88d36dad-hyphen-2.8.8.tar.gz
export ICU_TARBALL := c4a2d71ff56aec5ebfab2a3f059be99d-icu4c-56_1-src.tgz
export JFREEREPORT_FLOW_ENGINE_TARBALL := ba2930200c9f019c2d93a8c88c651a0f-flow-engine-0.9.4.zip
diff --git a/external/hunspell/UnpackedTarball_hunspell.mk b/external/hunspell/UnpackedTarball_hunspell.mk
index 8f14062..e70e33f 100644
--- a/external/hunspell/UnpackedTarball_hunspell.mk
+++ b/external/hunspell/UnpackedTarball_hunspell.mk
@@ -13,15 +13,7 @@ $(eval $(call gb_UnpackedTarball_set_tarball,hunspell,$(HUNSPELL_TARBALL)))

$(eval $(call gb_UnpackedTarball_add_patches,hunspell,\
	external/hunspell/hunspell-solaris.patch \
	external/hunspell/hunspell-1.3.2-overflow.patch \
	external/hunspell/hunspell-android.patch \
	external/hunspell/hunspell-1.3.2-nullptr.patch \
	external/hunspell/hunspell-1.3.2-literal.patch \
	external/hunspell/hunspell-fdo48017-wfopen.patch \
	external/hunspell/hunspell-morph-overflow.patch \
	external/hunspell/ubsan.patch.0 \
	external/hunspell/hunspell-1.3.3-rhbz1261421.patch \
	external/hunspell/hunspell-tdf95024-compound.patch \
	external/hunspell/hunspell-windows.patch \
))

ifeq ($(COM),MSC)
diff --git a/external/hunspell/hunspell-1.3.2-literal.patch b/external/hunspell/hunspell-1.3.2-literal.patch
deleted file mode 100644
index b0a8fb9..0000000
--- a/external/hunspell/hunspell-1.3.2-literal.patch
+++ /dev/null
@@ -1,11 +0,0 @@
--- misc/hunspell-1.3.2/src/tools/hunspell.cxx	2012-08-13 12:09:06.107017665 +0200
+++ misc/build/hunspell-1.3.2/src/tools/hunspell.cxx	2012-08-13 12:14:12.233500532 +0200
@@ -20,7 +20,7 @@
 #define HUNSPELL_VERSION VERSION
 #define INPUTLEN 50
 
-#define HUNSPELL_PIPE_HEADING "@(#) International Ispell Version 3.2.06 (but really Hunspell "VERSION")\n"
+#define HUNSPELL_PIPE_HEADING "@(#) International Ispell Version 3.2.06 (but really Hunspell " VERSION ")\n"
 #define HUNSPELL_HEADING "Hunspell "
 #define ODF_EXT "odt|ott|odp|otp|odg|otg|ods|ots"
 #define ENTITY_APOS "&apos;"
diff --git a/external/hunspell/hunspell-1.3.2-nullptr.patch b/external/hunspell/hunspell-1.3.2-nullptr.patch
deleted file mode 100644
index 624e6ce..0000000
--- a/external/hunspell/hunspell-1.3.2-nullptr.patch
+++ /dev/null
@@ -1,20 +0,0 @@
--- misc/hunspell-1.3.2/src/hunspell/affentry.hxx	2010-04-15 13:22:08.000000000 +0200
+++ misc/build/hunspell-1.3.2/src/hunspell/affentry.hxx	2012-08-13 12:08:48.568996730 +0200
@@ -27,7 +27,7 @@
   struct hentry *      checkword(const char * word, int len, char in_compound, 
                             const FLAG needflag = FLAG_NULL);
 
-  struct hentry *      check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = NULL);
+  struct hentry *      check_twosfx(const char * word, int len, char in_compound, const FLAG needflag = FLAG_NULL);
 
   char *      check_morph(const char * word, int len, char in_compound,
                             const FLAG needflag = FLAG_NULL);
@@ -90,7 +90,7 @@
 //                    const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, char in_compound=IN_CPD_NOT);
                     const FLAG cclass = FLAG_NULL, const FLAG needflag = FLAG_NULL, const FLAG badflag = 0);
 
-  struct hentry *   check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = NULL);
+  struct hentry *   check_twosfx(const char * word, int len, int optflags, PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
 
   char *      check_twosfx_morph(const char * word, int len, int optflags,
                  PfxEntry* ppfx, const FLAG needflag = FLAG_NULL);
diff --git a/external/hunspell/hunspell-1.3.2-overflow.patch b/external/hunspell/hunspell-1.3.2-overflow.patch
deleted file mode 100644
index 8500b483..0000000
--- a/external/hunspell/hunspell-1.3.2-overflow.patch
+++ /dev/null
@@ -1,91 +0,0 @@
--- misc/hunspell-1.3.2/src/hunspell/affixmgr.cxx	2010-02-27 12:59:53.000000000 +0100
+++ misc/build/hunspell-1.3.2/src/hunspell/affixmgr.cxx	2011-05-18 16:29:45.919141893 +0200
@@ -6,6 +6,8 @@
 #include <stdio.h>
 #include <ctype.h>
 
+#include <limits>
+
 #include <vector>
 
 #include "affixmgr.hxx"
@@ -4000,7 +4002,10 @@
              case 3: { 
                        np++;
                        numents = atoi(piece); 
-                       if (numents == 0) {
+                       if ((numents <= 0) ||
+                           ((::std::numeric_limits<size_t>::max()
+                                / sizeof(struct affentry)) < numents))
+                       {
                            char * err = pHMgr->encode_flag(aflag);
                            if (err) {
                                 HUNSPELL_WARNING(stderr, "error: line %d: bad entry number\n",
--- misc/hunspell-1.3.2/src/tools/munch.c	2010-02-27 21:49:49.000000000 +0100
+++ misc/build/hunspell-1.3.2/src/tools/munch.c	2011-05-18 15:53:53.427072106 +0200
@@ -4,6 +4,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -233,10 +233,19 @@
                     case 1: { achar = *piece; break; }
                     case 2: { if (*piece == 'Y') ff = XPRODUCT; break; }
                     case 3: { numents = atoi(piece); 
-                              ptr = malloc(numents * sizeof(struct affent));
-                              ptr->achar = achar;
-                              ptr->xpflg = ff;
-	                      fprintf(stderr,"parsing %c entries %d\n",achar,numents);
+                              if ((numents < 0) ||
+                                  ((SIZE_MAX/sizeof(struct affent)) < numents))
+                              {
+                                 fprintf(stderr,
+                                     "Error: too many entries: %d\n", numents);
+                                 numents = 0;
+                              } else {
+                                 ptr = malloc(numents * sizeof(struct affent));
+                                 ptr->achar = achar;
+                                 ptr->xpflg = ff;
+                                 fprintf(stderr,"parsing %c entries %d\n",
+                                         achar,numents);
+                              }
                               break;
                             }
 		    default: break;
--- misc/hunspell-1.3.2/src/tools/unmunch.c	2010-02-23 15:53:29.000000000 +0100
+++ misc/build/hunspell-1.3.2/src/tools/unmunch.c	2011-05-18 20:53:43.843599726 +0200
@@ -6,6 +6,7 @@
 #include <string.h>
 #include <unistd.h>
 #include <stdlib.h>
+#include <stdint.h>
 #include <stdio.h>
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -158,10 +159,19 @@
                     case 1: { achar = *piece; break; }
                     case 2: { if (*piece == 'Y') ff = XPRODUCT; break; }
                     case 3: { numents = atoi(piece); 
-                              ptr = malloc(numents * sizeof(struct affent));
-                              ptr->achar = achar;
-                              ptr->xpflg = ff;
-	                      fprintf(stderr,"parsing %c entries %d\n",achar,numents);
+                              if ((numents < 0) ||
+                                  ((SIZE_MAX/sizeof(struct affent)) < numents))
+                              {
+                                 fprintf(stderr,
+                                     "Error: too many entries: %d\n", numents);
+                                 numents = 0;
+                              } else {
+                                 ptr = malloc(numents * sizeof(struct affent));
+                                 ptr->achar = achar;
+                                 ptr->xpflg = ff;
+                                 fprintf(stderr,"parsing %c entries %d\n",
+                                         achar,numents);
+                              }
                               break;
                             }
 		    default: break;
diff --git a/external/hunspell/hunspell-1.3.3-rhbz1261421.patch b/external/hunspell/hunspell-1.3.3-rhbz1261421.patch
deleted file mode 100644
index 4354dd0..0000000
--- a/external/hunspell/hunspell-1.3.3-rhbz1261421.patch
+++ /dev/null
@@ -1,191 +0,0 @@
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
--- misc/hunspell-1.3.3/src/hunspell/hunspell.cxx
+++ misc/build/hunspell-1.3.3/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
--- misc/hunspell-1.3.3/src/hunspell/hunspell.hxx
+++ misc/build/hunspell-1.3.3/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
--- misc/hunspell-1.3.3/src/hunspell/replist.cxx
+++ misc/build/hunspell-1.3.3/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
--- misc/hunspell-1.3.3/src/hunspell/replist.hxx
+++ misc/build/hunspell-1.3.3/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
--- misc/hunspell-1.3.3/src/tools/hunspell.cxx
+++ misc/build/hunspell-1.3.3/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

diff --git a/external/hunspell/hunspell-android.patch b/external/hunspell/hunspell-android.patch
deleted file mode 100644
index 6653d63..0000000
--- a/external/hunspell/hunspell-android.patch
+++ /dev/null
@@ -1,20 +0,0 @@
--- misc/hunspell-1.3.2/config.sub	2010-02-23 10:08:48.000000000 +0100
+++ misc/build/hunspell-1.3.2/config.sub	2011-09-26 23:31:02.000000000 +0200
@@ -118,7 +118,7 @@
 # Here we must recognize all the valid KERNEL-OS combinations.
 maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
 case $maybe_os in
-  nto-qnx* | linux-gnu* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
+  nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | \
   kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | storm-chaos* | os2-emx* | rtmk-nova*)
     os=-$maybe_os
     basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
@@ -1161,7 +1161,7 @@
 	      | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
 	      | -chorusos* | -chorusrdb* \
 	      | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
-	      | -mingw32* | -linux-gnu* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
+	      | -mingw32* | -linux-gnu* | -linux-androideabi* | -linux-uclibc* | -uxpv* | -beos* | -mpeix* | -udk* \
 	      | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
 	      | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
 	      | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
diff --git a/external/hunspell/hunspell-fdo48017-wfopen.patch b/external/hunspell/hunspell-fdo48017-wfopen.patch
deleted file mode 100644
index 14f1db72..0000000
--- a/external/hunspell/hunspell-fdo48017-wfopen.patch
+++ /dev/null
@@ -1,19 +0,0 @@
diff -ru hunspell/src/hunspell/csutil.cxx build/hunspell/src/hunspell/csutil.cxx
--- hunspell/src/hunspell/csutil.cxx	2011-02-02 11:35:43.000000000 +0100
+++ build/hunspell/src/hunspell/csutil.cxx	2014-04-24 19:42:01.373285409 +0200
@@ -57,9 +57,14 @@
     if (strncmp(path, WIN32_LONG_PATH_PREFIX, 4) == 0) {
         int len = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0);
         wchar_t *buff = (wchar_t *) malloc(len * sizeof(wchar_t));
+        wchar_t *buff2 = (wchar_t *) malloc(len * sizeof(wchar_t));
+        FILE * f = NULL;
         MultiByteToWideChar(CP_UTF8, 0, path, -1, buff, len);
-        FILE * f = _wfopen(buff, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
+        if (_wfullpath( buff2, buff, len ) != NULL) {
+          f = _wfopen(buff2, (strcmp(mode, "r") == 0) ? L"r" : L"rb");
+        }
         free(buff);
+        free(buff2);
         return f;
     }
 #endif
diff --git a/external/hunspell/hunspell-morph-overflow.patch b/external/hunspell/hunspell-morph-overflow.patch
deleted file mode 100644
index fe7c4f7..0000000
--- a/external/hunspell/hunspell-morph-overflow.patch
+++ /dev/null
@@ -1,30 +0,0 @@
--- hunspell/src/hunspell/affixmgr.cxx	2014-09-24 16:11:10.750421303 +0200
+++ build/hunspell/src/hunspell/affixmgr.cxx	2014-09-26 15:25:09.448688908 +0200
@@ -2400,8 +2400,10 @@
                       }
                       mystrcat(*result, presult, MAXLNLEN);
                       if (m || (*m != '\0')) {
-                        sprintf(*result + strlen(*result), "%c%s%s%s", MSEP_FLD,
+                        char m2[MAXLNLEN];
+                        sprintf(m2, "%c%s%s%s", MSEP_FLD,
                             MORPH_PART, word + i, line_uniq_app(&m, MSEP_REC));
+                        mystrcat(*result, m2, MAXLNLEN);
                       }
                       if (m) free(m);
                       mystrcat(*result, "\n", MAXLNLEN);
@@ -2481,11 +2483,13 @@
                       }
                       mystrcat(*result, presult, MAXLNLEN);
                       if (m && (*m != '\0')) {
-                        sprintf(*result + strlen(*result), "%c%s%s%s", MSEP_FLD,
+                        char m2[MAXLNLEN];
+                        sprintf(m2, "%c%s%s%s", MSEP_FLD,
                             MORPH_PART, word + i, line_uniq_app(&m, MSEP_REC));
+                        mystrcat(*result, m2, MAXLNLEN);
                       }
                       if (m) free(m);
-                      sprintf(*result + strlen(*result), "%c", MSEP_REC);
+                      if (strlen(*result) + 1 < MAXLNLEN) sprintf(*result + strlen(*result), "%c", MSEP_REC);
                       ok = 1;
             }
 
diff --git a/external/hunspell/hunspell-tdf95024-compound.patch b/external/hunspell/hunspell-tdf95024-compound.patch
deleted file mode 100644
index 133cf4a..0000000
--- a/external/hunspell/hunspell-tdf95024-compound.patch
+++ /dev/null
@@ -1,108 +0,0 @@
From 42807f970ac2d65f0d13a7c57eb454b210e92240 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?L=C3=A1szl=C3=B3=20N=C3=A9meth?=
 <laszlo.nemeth@collabora.com>
Date: Mon, 12 Oct 2015 08:43:12 +0200
Subject: [PATCH] fix compound handling for new Hungarian orthography

The frequent cases of this compound limitation are handled by
the extended dictionary, but not these ones with both derivative
and inflectional suffixes.
---
 src/hunspell/affixmgr.cxx | 19 +++++++++++++++----
 src/hunspell/affixmgr.hxx |  1 +
 2 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/hunspell/affixmgr.cxx b/src/hunspell/affixmgr.cxx
index 0992e6e..0950425 100644
--- misc/hunspell-1.3.3/src/hunspell/affixmgr.cxx
+++ misc/build/hunspell-1.3.3/src/hunspell/affixmgr.cxx
@@ -139,8 +139,9 @@ AffixMgr::AffixMgr(const char * affpath, HashMgr** ptr, int * md, const char * k
   cpdvowels=NULL; // vowels (for calculating of Hungarian compounding limit, O(n) search! XXX)
   cpdvowels_utf16=NULL; // vowels for UTF-8 encoding (bsearch instead of O(n) search)
   cpdvowels_utf16_len=0; // vowels
-  pfxappnd=NULL; // previous prefix for counting the syllables of prefix BUG
-  sfxappnd=NULL; // previous suffix for counting a special syllables BUG
+  pfxappnd=NULL; // previous prefix for counting syllables of the prefix BUG
+  sfxappnd=NULL; // previous suffix for counting syllables of the suffix BUG
+  sfxextra=0; // modifier for syllable count of sfxappnd BUG
   cpdsyllablenum=NULL; // syllable count incrementing flag
   checknum=0; // checking numbers, and word with numbers
   wordchars=NULL; // letters + spec. word characters
@@ -1201,6 +1202,7 @@ struct hentry * AffixMgr::prefix_check(const char * word, int len, char in_compo
     pfx = NULL;
     pfxappnd = NULL;
     sfxappnd = NULL;
+    sfxextra = 0;
     
     // first handle the special case of 0 length prefixes
     PfxEntry * pe = pStart[0];
@@ -1261,6 +1263,7 @@ struct hentry * AffixMgr::prefix_check_twosfx(const char * word, int len,
 
     pfx = NULL;
     sfxappnd = NULL;
+    sfxextra = 0;
     
     // first handle the special case of 0 length prefixes
     PfxEntry * pe = pStart[0];
@@ -1302,6 +1305,7 @@ char * AffixMgr::prefix_check_morph(const char * word, int len, char in_compound
 
     pfx = NULL;
     sfxappnd = NULL;
+    sfxextra = 0;
     
     // first handle the special case of 0 length prefixes
     PfxEntry * pe = pStart[0];
@@ -1353,6 +1357,7 @@ char * AffixMgr::prefix_check_twosfx_morph(const char * word, int len,
 
     pfx = NULL;
     sfxappnd = NULL;
+    sfxextra = 0;
     
     // first handle the special case of 0 length prefixes
     PfxEntry * pe = pStart[0];
@@ -1993,7 +1998,7 @@ struct hentry * AffixMgr::compound_check(const char * word, int len,
                 // XXX only second suffix (inflections, not derivations)
                 if (sfxappnd) {
                     char * tmp = myrevstrdup(sfxappnd);
-                    numsyllable -= get_syllable(tmp, strlen(tmp));
+                    numsyllable -= get_syllable(tmp, strlen(tmp)) + sfxextra;
                     free(tmp);
                 }
 
@@ -2512,7 +2517,7 @@ int AffixMgr::compound_check_morph(const char * word, int len,
                 // XXX only second suffix (inflections, not derivations)
                 if (sfxappnd) {
                     char * tmp = myrevstrdup(sfxappnd);
-                    numsyllable -= get_syllable(tmp, strlen(tmp));
+                    numsyllable -= get_syllable(tmp, strlen(tmp)) + sfxextra;
                     free(tmp);
                 }
 
@@ -2696,6 +2701,12 @@ struct hentry * AffixMgr::suffix_check (const char * word, int len,
                     sfx=sptr; // BUG: sfx not stateless
                     sfxflag = sptr->getFlag(); // BUG: sfxflag not stateless
                     if (!sptr->getCont()) sfxappnd=sptr->getKey(); // BUG: sfxappnd not stateless
+// LANG_hu section: spec. Hungarian rule
+                    else if (langnum == LANG_hu && sptr->getKeyLen() && sptr->getKey()[0] == 'i' &&
+                        sptr->getKey()[1] != 'y' && sptr->getKey()[1] != 't') {
+                            sfxextra = 1;
+                    }
+// END of LANG_hu section
                     return rv;
                 }
              }
diff --git a/src/hunspell/affixmgr.hxx b/src/hunspell/affixmgr.hxx
index 2679b7f..8839814 100644
--- misc/hunspell-1.3.3/src/hunspell/affixmgr.hxx
+++ misc/build/hunspell-1.3.3/src/hunspell/affixmgr.hxx
@@ -155,6 +155,7 @@ class LIBHUNSPELL_DLL_EXPORTED AffixMgr
   char *              cpdsyllablenum;
   const char *        pfxappnd; // BUG: not stateless
   const char *        sfxappnd; // BUG: not stateless
+  int                 sfxextra; // BUG: not stateless
   FLAG                sfxflag;  // BUG: not stateless
   char *              derived;  // BUG: not stateless
   SfxEntry *          sfx;      // BUG: not stateless
-- 
1.9.1

diff --git a/external/hunspell/hunspell-windows.patch b/external/hunspell/hunspell-windows.patch
new file mode 100644
index 0000000..357272d
--- /dev/null
+++ b/external/hunspell/hunspell-windows.patch
@@ -0,0 +1,21 @@
--- /dev/null	2016-03-15 09:11:25.292954614 +0000
+++ misc/hunspell-1.3.4/src/hunspell/hunvisapi.h	2016-04-06 16:40:47.181698825 +0100
@@ -0,0 +1,18 @@
+#ifndef _HUNSPELL_VISIBILITY_H_
+#define _HUNSPELL_VISIBILITY_H_
+
+#if defined(HUNSPELL_STATIC)
+#  define LIBHUNSPELL_DLL_EXPORTED
+#elif defined(_MSC_VER)
+#  if defined(BUILDING_LIBHUNSPELL)
+#    define LIBHUNSPELL_DLL_EXPORTED __declspec(dllexport)
+#  else
+#    define LIBHUNSPELL_DLL_EXPORTED __declspec(dllimport)
+#  endif
+#elif defined(BUILDING_LIBHUNSPELL) && 1
+#  define LIBHUNSPELL_DLL_EXPORTED __attribute__((__visibility__("default")))
+#else
+#  define LIBHUNSPELL_DLL_EXPORTED
+#endif
+
+#endif
diff --git a/external/hunspell/ubsan.patch.0 b/external/hunspell/ubsan.patch.0
deleted file mode 100644
index b52802d..0000000
--- a/external/hunspell/ubsan.patch.0
+++ /dev/null
@@ -1,35 +0,0 @@
--- src/hunspell/hashmgr.cxx
+++ src/hunspell/hashmgr.cxx
@@ -479,7 +479,7 @@
 
 int HashMgr::hash(const char * word) const
 {
-    long  hv = 0;
+    unsigned long  hv = 0;
     for (int i=0; i < 4  &&  *word != 0; i++)
         hv = (hv << 8) | (*word++);
     while (*word != 0) {
--- src/hunspell/csutil.cxx
+++ src/hunspell/csutil.cxx
@@ -147,7 +147,7 @@
         case 0xd0: {    // 2-byte UTF-8 codes
             if ((*(u8+1) & 0xc0) == 0x80) {
                 u2->h = (*u8 & 0x1f) >> 2;
-                u2->l = (*u8 << 6) + (*(u8+1) & 0x3f);
+                u2->l = (*reinterpret_cast<unsigned char const *>(u8) << 6) + (*(u8+1) & 0x3f);
                 u8++;
             } else {
                 HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %ld. character position:\n%s\n", static_cast<long>(u8 - (signed char *)src), src);
@@ -158,10 +158,10 @@
         }
         case 0xe0: {    // 3-byte UTF-8 codes
             if ((*(u8+1) & 0xc0) == 0x80) {
-                u2->h = ((*u8 & 0x0f) << 4) + ((*(u8+1) & 0x3f) >> 2);
+                u2->h = ((*reinterpret_cast<unsigned char const *>(u8) & 0x0f) << 4) + ((*(u8+1) & 0x3f) >> 2);
                 u8++;
                 if ((*(u8+1) & 0xc0) == 0x80) {
-                    u2->l = (*u8 << 6) + (*(u8+1) & 0x3f);
+                    u2->l = (*reinterpret_cast<unsigned char const *>(u8) << 6) + (*(u8+1) & 0x3f);
                     u8++;
                 } else {
                     HUNSPELL_WARNING(stderr, "UTF-8 encoding error. Missing continuation byte in %ld. character position:\n%s\n", static_cast<long>(u8 - (signed char *)src), src);