mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
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().
This commit is contained in:
42
src/spell.c
42
src/spell.c
@@ -3123,7 +3123,7 @@ spell_iswordp(
|
|||||||
|
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
l = MB_BYTE2LEN(*p);
|
l = MB_PTR2LEN(p);
|
||||||
s = p;
|
s = p;
|
||||||
if (l == 1)
|
if (l == 1)
|
||||||
{
|
{
|
||||||
@@ -3808,6 +3808,10 @@ spell_find_suggest(
|
|||||||
vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
|
vim_strncpy(su->su_badword, su->su_badptr, su->su_badlen);
|
||||||
(void)spell_casefold(su->su_badptr, su->su_badlen,
|
(void)spell_casefold(su->su_badptr, su->su_badlen,
|
||||||
su->su_fbadword, MAXWLEN);
|
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 */
|
/* get caps flags for bad word */
|
||||||
su->su_badflags = badword_captype(su->su_badptr,
|
su->su_badflags = badword_captype(su->su_badptr,
|
||||||
su->su_badptr + su->su_badlen);
|
su->su_badptr + su->su_badlen);
|
||||||
@@ -4937,12 +4941,7 @@ suggest_trie_walk(
|
|||||||
{
|
{
|
||||||
int l;
|
int l;
|
||||||
|
|
||||||
#ifdef FEAT_MBYTE
|
l = MB_PTR2LEN(fword + sp->ts_fidx);
|
||||||
if (has_mbyte)
|
|
||||||
l = MB_BYTE2LEN(fword[sp->ts_fidx]);
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
l = 1;
|
|
||||||
if (fword_ends)
|
if (fword_ends)
|
||||||
{
|
{
|
||||||
/* Copy the skipped character to preword. */
|
/* Copy the skipped character to preword. */
|
||||||
@@ -5109,9 +5108,8 @@ suggest_trie_walk(
|
|||||||
/* Correct ts_fidx for the byte length of the
|
/* Correct ts_fidx for the byte length of the
|
||||||
* character (we didn't check that before). */
|
* character (we didn't check that before). */
|
||||||
sp->ts_fidx = sp->ts_fcharstart
|
sp->ts_fidx = sp->ts_fcharstart
|
||||||
+ MB_BYTE2LEN(
|
+ MB_PTR2LEN(
|
||||||
fword[sp->ts_fcharstart]);
|
fword + sp->ts_fcharstart);
|
||||||
|
|
||||||
/* For changing a composing character adjust
|
/* For changing a composing character adjust
|
||||||
* the score from SCORE_SUBST to
|
* the score from SCORE_SUBST to
|
||||||
* SCORE_SUBCOMP. */
|
* SCORE_SUBCOMP. */
|
||||||
@@ -5232,7 +5230,7 @@ suggest_trie_walk(
|
|||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
c = mb_ptr2char(fword + sp->ts_fidx);
|
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))
|
if (enc_utf8 && utf_iscomposing(c))
|
||||||
stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
|
stack[depth].ts_score -= SCORE_DEL - SCORE_DELCOMP;
|
||||||
else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
|
else if (c == mb_ptr2char(fword + stack[depth].ts_fidx))
|
||||||
@@ -5456,9 +5454,9 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = MB_BYTE2LEN(*p);
|
n = MB_PTR2LEN(p);
|
||||||
c = mb_ptr2char(p + n);
|
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);
|
mb_char2bytes(c, p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -5550,11 +5548,11 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = MB_BYTE2LEN(*p);
|
n = MB_PTR2LEN(p);
|
||||||
c2 = mb_ptr2char(p + n);
|
c2 = mb_ptr2char(p + n);
|
||||||
fl = MB_BYTE2LEN(p[n]);
|
fl = MB_PTR2LEN(p + n);
|
||||||
c = mb_ptr2char(p + n + fl);
|
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);
|
mch_memmove(p + fl + tl, p, n);
|
||||||
mb_char2bytes(c, p);
|
mb_char2bytes(c, p);
|
||||||
mb_char2bytes(c2, p + tl);
|
mb_char2bytes(c2, p + tl);
|
||||||
@@ -5627,10 +5625,10 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = MB_BYTE2LEN(*p);
|
n = MB_PTR2LEN(p);
|
||||||
n += MB_BYTE2LEN(p[n]);
|
n += MB_PTR2LEN(p + n);
|
||||||
c = mb_ptr2char(p + n);
|
c = mb_ptr2char(p + n);
|
||||||
tl = MB_BYTE2LEN(p[n]);
|
tl = MB_PTR2LEN(p + n);
|
||||||
mch_memmove(p + tl, p, n);
|
mch_memmove(p + tl, p, n);
|
||||||
mb_char2bytes(c, p);
|
mb_char2bytes(c, p);
|
||||||
}
|
}
|
||||||
@@ -5693,9 +5691,9 @@ suggest_trie_walk(
|
|||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
c = mb_ptr2char(p);
|
c = mb_ptr2char(p);
|
||||||
tl = MB_BYTE2LEN(*p);
|
tl = MB_PTR2LEN(p);
|
||||||
n = MB_BYTE2LEN(p[tl]);
|
n = MB_PTR2LEN(p + tl);
|
||||||
n += MB_BYTE2LEN(p[tl + n]);
|
n += MB_PTR2LEN(p + tl + n);
|
||||||
mch_memmove(p, p + tl, n);
|
mch_memmove(p, p + tl, n);
|
||||||
mb_char2bytes(c, p + n);
|
mb_char2bytes(c, p + n);
|
||||||
}
|
}
|
||||||
|
@@ -18,3 +18,12 @@ func Test_wrap_search()
|
|||||||
bwipe!
|
bwipe!
|
||||||
set nospell
|
set nospell
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_z_equal_on_invalid_utf8_word()
|
||||||
|
split
|
||||||
|
set spell
|
||||||
|
call setline(1, "\xff")
|
||||||
|
norm z=
|
||||||
|
set nospell
|
||||||
|
bwipe!
|
||||||
|
endfunc
|
||||||
|
@@ -764,6 +764,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
582,
|
||||||
/**/
|
/**/
|
||||||
581,
|
581,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user