]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 8.0.0582: illegal memory access with z= command v8.0.0582
authorBram Moolenaar <Bram@vim.org>
Sat, 22 Apr 2017 21:49:52 +0000 (23:49 +0200)
committerBram Moolenaar <Bram@vim.org>
Sat, 22 Apr 2017 21:49:52 +0000 (23:49 +0200)
Problem:    Illegal memory access with z= command. (Dominique Pelle)
Solution:   Avoid case folded text to be longer than the original text.  Use
            MB_PTR2LEN() instead of MB_BYTE2LEN().

src/spell.c
src/testdir/test_spell.vim
src/version.c

index ed0db8c8aa56df7e44844b1a5d938fc68a70c1de..118e78bc0e0d12380239ab0d785d5504ff3c97ac 100644 (file)
@@ -3123,7 +3123,7 @@ spell_iswordp(
 
     if (has_mbyte)
     {
-       l = MB_BYTE2LEN(*p);
+       l = MB_PTR2LEN(p);
        s = p;
        if (l == 1)
        {
@@ -3808,6 +3808,10 @@ spell_find_suggest(
     vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
     (void)spell_casefold(su->su_badptr, su->su_badlen,
                                                    su->su_fbadword, MAXWLEN);
+    /* TODO: make this work if the case-folded text is longer than the original
+     * text. Currently an illegal byte causes wrong pointer computations. */
+    su->su_fbadword[su->su_badlen] = NUL;
+
     /* get caps flags for bad word */
     su->su_badflags = badword_captype(su->su_badptr,
                                               su->su_badptr + su->su_badlen);
@@ -4937,12 +4941,7 @@ suggest_trie_walk(
                        {
                            int     l;
 
-#ifdef FEAT_MBYTE
-                           if (has_mbyte)
-                               l = MB_BYTE2LEN(fword[sp->ts_fidx]);
-                           else
-#endif
-                               l = 1;
+                           l = MB_PTR2LEN(fword + sp->ts_fidx);
                            if (fword_ends)
                            {
                                /* Copy the skipped character to preword. */
@@ -5109,9 +5108,8 @@ suggest_trie_walk(
                                /* Correct ts_fidx for the byte length of the
                                 * character (we didn't check that before). */
                                sp->ts_fidx = sp->ts_fcharstart
-                                           + MB_BYTE2LEN(
-                                                   fword[sp->ts_fcharstart]);
-
+                                           + MB_PTR2LEN(
+                                                   fword + sp->ts_fcharstart);
                                /* For changing a composing character adjust
                                 * the score from SCORE_SUBST to
                                 * SCORE_SUBCOMP. */
@@ -5232,7 +5230,7 @@ suggest_trie_walk(
                if (has_mbyte)
                {
                    c = mb_ptr2char(fword + sp->ts_fidx);
-                   stack[depth].ts_fidx += MB_BYTE2LEN(fword[sp->ts_fidx]);
+                   stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
                    if (enc_utf8 && utf_iscomposing(c))
                        stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
                    else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
@@ -5456,9 +5454,9 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
+               n = MB_PTR2LEN(p);
                c = mb_ptr2char(p + n);
-               mch_memmove(p + MB_BYTE2LEN(p[n]), p, n);
+               mch_memmove(p + MB_PTR2LEN(p + n), p, n);
                mb_char2bytes(c, p);
            }
            else
@@ -5550,11 +5548,11 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
+               n = MB_PTR2LEN(p);
                c2 = mb_ptr2char(p + n);
-               fl = MB_BYTE2LEN(p[n]);
+               fl = MB_PTR2LEN(p + n);
                c = mb_ptr2char(p + n + fl);
-               tl = MB_BYTE2LEN(p[n + fl]);
+               tl = MB_PTR2LEN(p + n + fl);
                mch_memmove(p + fl + tl, p, n);
                mb_char2bytes(c, p);
                mb_char2bytes(c2, p + tl);
@@ -5627,10 +5625,10 @@ suggest_trie_walk(
 #ifdef FEAT_MBYTE
            if (has_mbyte)
            {
-               n = MB_BYTE2LEN(*p);
-               n += MB_BYTE2LEN(p[n]);
+               n = MB_PTR2LEN(p);
+               n += MB_PTR2LEN(p + n);
                c = mb_ptr2char(p + n);
-               tl = MB_BYTE2LEN(p[n]);
+               tl = MB_PTR2LEN(p + n);
                mch_memmove(p + tl, p, n);
                mb_char2bytes(c, p);
            }
@@ -5693,9 +5691,9 @@ suggest_trie_walk(
            if (has_mbyte)
            {
                c = mb_ptr2char(p);
-               tl = MB_BYTE2LEN(*p);
-               n = MB_BYTE2LEN(p[tl]);
-               n += MB_BYTE2LEN(p[tl + n]);
+               tl = MB_PTR2LEN(p);
+               n = MB_PTR2LEN(p + tl);
+               n += MB_PTR2LEN(p + tl + n);
                mch_memmove(p, p + tl, n);
                mb_char2bytes(c, p + n);
            }
index e6c3729b1188c911f55c9518c2005c17f33d3b0c..0688d615e7aa342973e9c55b17541d1148817849 100644 (file)
@@ -18,3 +18,12 @@ func Test_wrap_search()
   bwipe!
   set nospell
 endfunc
+
+func Test_z_equal_on_invalid_utf8_word()
+  split
+  set spell
+  call setline(1, "\xff")
+  norm z=
+  set nospell
+  bwipe!
+endfunc
index 3f74d6e396de2fbaa20edfcf95445a5659797d9b..0533f574d23603ff320a6f5c4bf5e69c192177d5 100644 (file)
@@ -764,6 +764,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    582,
 /**/
     581,
 /**/