Skip to content

Commit 5b276aa

Browse files
committed
patch 8.0.0582: illegal memory access with z= command
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().
1 parent 94be619 commit 5b276aa

File tree

3 files changed

+31
-22
lines changed

3 files changed

+31
-22
lines changed

src/spell.c

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3123,7 +3123,7 @@ spell_iswordp(
31233123

31243124
if (has_mbyte)
31253125
{
3126-
l = MB_BYTE2LEN(*p);
3126+
l = MB_PTR2LEN(p);
31273127
s = p;
31283128
if (l == 1)
31293129
{
@@ -3808,6 +3808,10 @@ spell_find_suggest(
38083808
vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
38093809
(void)spell_casefold(su->su_badptr, su->su_badlen,
38103810
su->su_fbadword, MAXWLEN);
3811+
/* TODO: make this work if the case-folded text is longer than the original
3812+
* text. Currently an illegal byte causes wrong pointer computations. */
3813+
su->su_fbadword[su->su_badlen] = NUL;
3814+
38113815
/* get caps flags for bad word */
38123816
su->su_badflags = badword_captype(su->su_badptr,
38133817
su->su_badptr + su->su_badlen);
@@ -4937,12 +4941,7 @@ suggest_trie_walk(
49374941
{
49384942
int l;
49394943

4940-
#ifdef FEAT_MBYTE
4941-
if (has_mbyte)
4942-
l = MB_BYTE2LEN(fword[sp->ts_fidx]);
4943-
else
4944-
#endif
4945-
l = 1;
4944+
l = MB_PTR2LEN(fword + sp->ts_fidx);
49464945
if (fword_ends)
49474946
{
49484947
/* Copy the skipped character to preword. */
@@ -5109,9 +5108,8 @@ suggest_trie_walk(
51095108
/* Correct ts_fidx for the byte length of the
51105109
* character (we didn't check that before). */
51115110
sp->ts_fidx = sp->ts_fcharstart
5112-
+ MB_BYTE2LEN(
5113-
fword[sp->ts_fcharstart]);
5114-
5111+
+ MB_PTR2LEN(
5112+
fword + sp->ts_fcharstart);
51155113
/* For changing a composing character adjust
51165114
* the score from SCORE_SUBST to
51175115
* SCORE_SUBCOMP. */
@@ -5232,7 +5230,7 @@ suggest_trie_walk(
52325230
if (has_mbyte)
52335231
{
52345232
c = mb_ptr2char(fword + sp->ts_fidx);
5235-
stack[depth].ts_fidx += MB_BYTE2LEN(fword[sp->ts_fidx]);
5233+
stack[depth].ts_fidx += MB_PTR2LEN(fword + sp->ts_fidx);
52365234
if (enc_utf8 && utf_iscomposing(c))
52375235
stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
52385236
else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
@@ -5456,9 +5454,9 @@ suggest_trie_walk(
54565454
#ifdef FEAT_MBYTE
54575455
if (has_mbyte)
54585456
{
5459-
n = MB_BYTE2LEN(*p);
5457+
n = MB_PTR2LEN(p);
54605458
c = mb_ptr2char(p + n);
5461-
mch_memmove(p + MB_BYTE2LEN(p[n]), p, n);
5459+
mch_memmove(p + MB_PTR2LEN(p + n), p, n);
54625460
mb_char2bytes(c, p);
54635461
}
54645462
else
@@ -5550,11 +5548,11 @@ suggest_trie_walk(
55505548
#ifdef FEAT_MBYTE
55515549
if (has_mbyte)
55525550
{
5553-
n = MB_BYTE2LEN(*p);
5551+
n = MB_PTR2LEN(p);
55545552
c2 = mb_ptr2char(p + n);
5555-
fl = MB_BYTE2LEN(p[n]);
5553+
fl = MB_PTR2LEN(p + n);
55565554
c = mb_ptr2char(p + n + fl);
5557-
tl = MB_BYTE2LEN(p[n + fl]);
5555+
tl = MB_PTR2LEN(p + n + fl);
55585556
mch_memmove(p + fl + tl, p, n);
55595557
mb_char2bytes(c, p);
55605558
mb_char2bytes(c2, p + tl);
@@ -5627,10 +5625,10 @@ suggest_trie_walk(
56275625
#ifdef FEAT_MBYTE
56285626
if (has_mbyte)
56295627
{
5630-
n = MB_BYTE2LEN(*p);
5631-
n += MB_BYTE2LEN(p[n]);
5628+
n = MB_PTR2LEN(p);
5629+
n += MB_PTR2LEN(p + n);
56325630
c = mb_ptr2char(p + n);
5633-
tl = MB_BYTE2LEN(p[n]);
5631+
tl = MB_PTR2LEN(p + n);
56345632
mch_memmove(p + tl, p, n);
56355633
mb_char2bytes(c, p);
56365634
}
@@ -5693,9 +5691,9 @@ suggest_trie_walk(
56935691
if (has_mbyte)
56945692
{
56955693
c = mb_ptr2char(p);
5696-
tl = MB_BYTE2LEN(*p);
5697-
n = MB_BYTE2LEN(p[tl]);
5698-
n += MB_BYTE2LEN(p[tl + n]);
5694+
tl = MB_PTR2LEN(p);
5695+
n = MB_PTR2LEN(p + tl);
5696+
n += MB_PTR2LEN(p + tl + n);
56995697
mch_memmove(p, p + tl, n);
57005698
mb_char2bytes(c, p + n);
57015699
}

src/testdir/test_spell.vim

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,12 @@ func Test_wrap_search()
1818
bwipe!
1919
set nospell
2020
endfunc
21+
22+
func Test_z_equal_on_invalid_utf8_word()
23+
split
24+
set spell
25+
call setline(1, "\xff")
26+
norm z=
27+
set nospell
28+
bwipe!
29+
endfunc

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static char *(features[]) =
764764

765765
static int included_patches[] =
766766
{ /* Add new patch number below this line */
767+
/**/
768+
582,
767769
/**/
768770
581,
769771
/**/

0 commit comments

Comments
 (0)