Bug 983817 follow-up: Add the fix for the bug to the hunspell patches directory
authorEhsan Akhgari <ehsan@mozilla.com>
Wed, 11 Mar 2015 22:03:00 -0400
changeset 263472 99814e9730de09eaeb0a3dc2d7ce5deeefaae5db
parent 263471 78f687fd9c11ace7db8d9a1bfdf98fb32798cb27
child 263473 b6329532e4e9507e3b5f5439bb279e3a6f561110
push id830
push userraliiev@mozilla.com
push dateFri, 19 Jun 2015 19:24:37 +0000
treeherdermozilla-release@932614382a68 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs983817
milestone39.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 983817 follow-up: Add the fix for the bug to the hunspell patches directory DONTBUILD
extensions/spellcheck/hunspell/src/patches/10-983817.diff
new file mode 100644
--- /dev/null
+++ b/extensions/spellcheck/hunspell/src/patches/10-983817.diff
@@ -0,0 +1,78 @@
+Bug 983817 - Pad heap allocations passed to flag_qsort() on x86 Linux to work around gcc bug affecting Ubuntu packages.  r=froydnj
+
+diff --git a/extensions/spellcheck/hunspell/src/hashmgr.cxx b/extensions/spellcheck/hunspell/src/hashmgr.cxx
+index 12adf42..95ff23f 100644
+--- a/extensions/spellcheck/hunspell/src/hashmgr.cxx
++++ b/extensions/spellcheck/hunspell/src/hashmgr.cxx
+@@ -11,6 +11,20 @@
+ #include "csutil.hxx"
+ #include "atypes.hxx"
+ 
++// The gcc used to build 32-bit builds of Firefox on Ubuntu
++// miscompiles flag_qsort, using a 32-bit read instead of a 16-bit
++// read while quicksorting an array of 16-bit units.  This causes
++// one of the top Firefox crashes.
++// Given that I haven't been able to produce a reduced testcase to give
++// to gcc developers, just work around the bug by allocating an extra 2
++// bytes on the heap arrays passed to flag_qsort().
++// See https://bugzilla.mozilla.org/show_bug.cgi?id=983817 .
++#if defined(__linux__) && defined(__i386__) && defined(__GNUC__)
++#define EXTRA_QSORT_ALLOC_SIZE 1
++#else
++#define EXTRA_QSORT_ALLOC_SIZE 0
++#endif
++
+ // build a hash table from a munched word list
+ 
+ HashMgr::HashMgr(const char * tpath, const char * apath, const char * key)
+@@ -265,8 +279,8 @@ int HashMgr::remove(const char * word)
+     struct hentry * dp = lookup(word);
+     while (dp) {
+         if (dp->alen == 0 || !TESTAFF(dp->astr, forbiddenword, dp->alen)) {
+-            unsigned short * flags =
+-                (unsigned short *) malloc(sizeof(short) * (dp->alen + 1));
++            unsigned short * flags = (unsigned short *)
++              malloc(sizeof(short) * (dp->alen + 1 + EXTRA_QSORT_ALLOC_SIZE));
+             if (!flags) return 1;
+             for (int i = 0; i < dp->alen; i++) flags[i] = dp->astr[i];
+             flags[dp->alen] = forbiddenword;
+@@ -508,7 +522,8 @@ int HashMgr::decode_flags(unsigned short ** result, char * flags, FileMgr * af)
+         len = strlen(flags);
+         if (len%2 == 1) HUNSPELL_WARNING(stderr, "error: line %d: bad flagvector\n", af->getlinenum());
+         len /= 2;
+-        *result = (unsigned short *) malloc(len * sizeof(short));
++        *result = (unsigned short *)
++          malloc((len + EXTRA_QSORT_ALLOC_SIZE) * sizeof(short));
+         if (!*result) return -1;
+         for (int i = 0; i < len; i++) {
+             (*result)[i] = (((unsigned short) flags[i * 2]) << 8) + (unsigned short) flags[i * 2 + 1]; 
+@@ -524,7 +539,8 @@ int HashMgr::decode_flags(unsigned short ** result, char * flags, FileMgr * af)
+         for (p = flags; *p; p++) {
+           if (*p == ',') len++;
+         }
+-        *result = (unsigned short *) malloc(len * sizeof(short));
++        *result = (unsigned short *)
++          malloc((len + EXTRA_QSORT_ALLOC_SIZE) * sizeof(short));
+         if (!*result) return -1;
+         dest = *result;
+         for (p = flags; *p; p++) {
+@@ -548,7 +564,8 @@ int HashMgr::decode_flags(unsigned short ** result, char * flags, FileMgr * af)
+       case FLAG_UNI: { // UTF-8 characters
+         w_char w[BUFSIZE/2];
+         len = u8_u16(w, BUFSIZE/2, flags);
+-        *result = (unsigned short *) malloc(len * sizeof(short));
++        *result =
++          (unsigned short *) malloc((len + EXTRA_QSORT_ALLOC_SIZE) * sizeof(short));
+         if (!*result) return -1;
+         memcpy(*result, w, len * sizeof(short));
+         break;
+@@ -556,7 +573,8 @@ int HashMgr::decode_flags(unsigned short ** result, char * flags, FileMgr * af)
+       default: { // Ispell's one-character flags (erfg -> e r f g)
+         unsigned short * dest;
+         len = strlen(flags);
+-        *result = (unsigned short *) malloc(len * sizeof(short));
++        *result = (unsigned short *)
++          malloc((len + EXTRA_QSORT_ALLOC_SIZE) * sizeof(short));
+         if (!*result) return -1;
+         dest = *result;
+         for (unsigned char * p = (unsigned char *) flags; *p; p++) {