mirror of
https://github.com/vim/vim.git
synced 2025-09-26 04:04:07 -04:00
patch 7.4.2223
Problem: Buffer overflow when using latin1 character with feedkeys(). Solution: Check for an illegal character. Add a test.
This commit is contained in:
@@ -2114,6 +2114,7 @@ test_arglist \
|
|||||||
test_set \
|
test_set \
|
||||||
test_signs \
|
test_signs \
|
||||||
test_sort \
|
test_sort \
|
||||||
|
test_source_utf8 \
|
||||||
test_startup \
|
test_startup \
|
||||||
test_startup_utf8 \
|
test_startup_utf8 \
|
||||||
test_stat \
|
test_stat \
|
||||||
|
@@ -11166,7 +11166,7 @@ f_strgetchar(typval_T *argvars, typval_T *rettv)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
--charidx;
|
--charidx;
|
||||||
byteidx += mb_cptr2len(str + byteidx);
|
byteidx += MB_CPTR2LEN(str + byteidx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
@@ -11326,7 +11326,7 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
|
|||||||
if (nchar > 0)
|
if (nchar > 0)
|
||||||
while (nchar > 0 && nbyte < slen)
|
while (nchar > 0 && nbyte < slen)
|
||||||
{
|
{
|
||||||
nbyte += mb_cptr2len(p + nbyte);
|
nbyte += MB_CPTR2LEN(p + nbyte);
|
||||||
--nchar;
|
--nchar;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -11341,7 +11341,7 @@ f_strcharpart(typval_T *argvars, typval_T *rettv)
|
|||||||
if (off < 0)
|
if (off < 0)
|
||||||
len += 1;
|
len += 1;
|
||||||
else
|
else
|
||||||
len += mb_cptr2len(p + off);
|
len += MB_CPTR2LEN(p + off);
|
||||||
--charlen;
|
--charlen;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4658,8 +4658,16 @@ vim_strsave_escape_csi(
|
|||||||
char_u *res;
|
char_u *res;
|
||||||
char_u *s, *d;
|
char_u *s, *d;
|
||||||
|
|
||||||
/* Need a buffer to hold up to three times as much. */
|
/* Need a buffer to hold up to three times as much. Four in case of an
|
||||||
res = alloc((unsigned)(STRLEN(p) * 3) + 1);
|
* illegal utf-8 byte:
|
||||||
|
* 0xc0 -> 0xc3 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER */
|
||||||
|
res = alloc((unsigned)(STRLEN(p) *
|
||||||
|
#ifdef FEAT_MBYTE
|
||||||
|
4
|
||||||
|
#else
|
||||||
|
3
|
||||||
|
#endif
|
||||||
|
) + 1);
|
||||||
if (res != NULL)
|
if (res != NULL)
|
||||||
{
|
{
|
||||||
d = res;
|
d = res;
|
||||||
@@ -4674,22 +4682,10 @@ vim_strsave_escape_csi(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
#ifdef FEAT_MBYTE
|
|
||||||
int len = mb_char2len(PTR2CHAR(s));
|
|
||||||
int len2 = mb_ptr2len(s);
|
|
||||||
#endif
|
|
||||||
/* Add character, possibly multi-byte to destination, escaping
|
/* Add character, possibly multi-byte to destination, escaping
|
||||||
* CSI and K_SPECIAL. */
|
* CSI and K_SPECIAL. Be careful, it can be an illegal byte! */
|
||||||
d = add_char2buf(PTR2CHAR(s), d);
|
d = add_char2buf(PTR2CHAR(s), d);
|
||||||
#ifdef FEAT_MBYTE
|
s += MB_CPTR2LEN(s);
|
||||||
while (len < len2)
|
|
||||||
{
|
|
||||||
/* add following combining char */
|
|
||||||
d = add_char2buf(PTR2CHAR(s + len), d);
|
|
||||||
len += mb_char2len(PTR2CHAR(s + len));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
mb_ptr_adv(s);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*d = NUL;
|
*d = NUL;
|
||||||
|
@@ -274,7 +274,7 @@
|
|||||||
/* Backup multi-byte pointer. Only use with "p" > "s" ! */
|
/* Backup multi-byte pointer. Only use with "p" > "s" ! */
|
||||||
# define mb_ptr_back(s, p) p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
|
# define mb_ptr_back(s, p) p -= has_mbyte ? ((*mb_head_off)(s, p - 1) + 1) : 1
|
||||||
/* get length of multi-byte char, not including composing chars */
|
/* get length of multi-byte char, not including composing chars */
|
||||||
# define mb_cptr2len(p) (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
|
# define MB_CPTR2LEN(p) (enc_utf8 ? utf_ptr2len(p) : (*mb_ptr2len)(p))
|
||||||
|
|
||||||
# define MB_COPY_CHAR(f, t) if (has_mbyte) mb_copy_char(&f, &t); else *t++ = *f++
|
# define MB_COPY_CHAR(f, t) if (has_mbyte) mb_copy_char(&f, &t); else *t++ = *f++
|
||||||
# define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
|
# define MB_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
|
||||||
@@ -282,6 +282,7 @@
|
|||||||
# define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
|
# define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
|
||||||
#else
|
#else
|
||||||
# define MB_PTR2LEN(p) 1
|
# define MB_PTR2LEN(p) 1
|
||||||
|
# define MB_CPTR2LEN(p) 1
|
||||||
# define mb_ptr_adv(p) ++p
|
# define mb_ptr_adv(p) ++p
|
||||||
# define mb_cptr_adv(p) ++p
|
# define mb_cptr_adv(p) ++p
|
||||||
# define mb_ptr_back(s, p) --p
|
# define mb_ptr_back(s, p) --p
|
||||||
|
@@ -4806,7 +4806,7 @@ mch_call_shell(
|
|||||||
* round. */
|
* round. */
|
||||||
for (p = buffer; p < buffer + len; p += l)
|
for (p = buffer; p < buffer + len; p += l)
|
||||||
{
|
{
|
||||||
l = mb_cptr2len(p);
|
l = MB_CPTR2LEN(p);
|
||||||
if (l == 0)
|
if (l == 0)
|
||||||
l = 1; /* NUL byte? */
|
l = 1; /* NUL byte? */
|
||||||
else if (MB_BYTE2LEN(*p) != l)
|
else if (MB_BYTE2LEN(*p) != l)
|
||||||
|
@@ -4370,7 +4370,7 @@ dump_pipe(int options,
|
|||||||
* round. */
|
* round. */
|
||||||
for (p = buffer; p < buffer + len; p += l)
|
for (p = buffer; p < buffer + len; p += l)
|
||||||
{
|
{
|
||||||
l = mb_cptr2len(p);
|
l = MB_CPTR2LEN(p);
|
||||||
if (l == 0)
|
if (l == 0)
|
||||||
l = 1; /* NUL byte? */
|
l = 1; /* NUL byte? */
|
||||||
else if (MB_BYTE2LEN(*p) != l)
|
else if (MB_BYTE2LEN(*p) != l)
|
||||||
|
22
src/spell.c
22
src/spell.c
@@ -5379,7 +5379,7 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = mb_cptr2len(p);
|
n = MB_CPTR2LEN(p);
|
||||||
c = mb_ptr2char(p);
|
c = mb_ptr2char(p);
|
||||||
if (p[n] == NUL)
|
if (p[n] == NUL)
|
||||||
c2 = NUL;
|
c2 = NUL;
|
||||||
@@ -5477,9 +5477,9 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = mb_cptr2len(p);
|
n = MB_CPTR2LEN(p);
|
||||||
c = mb_ptr2char(p);
|
c = mb_ptr2char(p);
|
||||||
fl = mb_cptr2len(p + n);
|
fl = MB_CPTR2LEN(p + n);
|
||||||
c2 = mb_ptr2char(p + n);
|
c2 = mb_ptr2char(p + n);
|
||||||
if (!soundfold && !spell_iswordp(p + n + fl, curwin))
|
if (!soundfold && !spell_iswordp(p + n + fl, curwin))
|
||||||
c3 = c; /* don't swap non-word char */
|
c3 = c; /* don't swap non-word char */
|
||||||
@@ -5596,10 +5596,10 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = mb_cptr2len(p);
|
n = MB_CPTR2LEN(p);
|
||||||
c = mb_ptr2char(p);
|
c = mb_ptr2char(p);
|
||||||
fl = mb_cptr2len(p + n);
|
fl = MB_CPTR2LEN(p + n);
|
||||||
fl += mb_cptr2len(p + n + fl);
|
fl += MB_CPTR2LEN(p + n + fl);
|
||||||
mch_memmove(p, p + n, fl);
|
mch_memmove(p, p + n, fl);
|
||||||
mb_char2bytes(c, p + fl);
|
mb_char2bytes(c, p + fl);
|
||||||
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
|
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
|
||||||
@@ -5661,10 +5661,10 @@ suggest_trie_walk(
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
n = mb_cptr2len(p);
|
n = MB_CPTR2LEN(p);
|
||||||
n += mb_cptr2len(p + n);
|
n += MB_CPTR2LEN(p + n);
|
||||||
c = mb_ptr2char(p + n);
|
c = mb_ptr2char(p + n);
|
||||||
tl = mb_cptr2len(p + n);
|
tl = MB_CPTR2LEN(p + n);
|
||||||
mch_memmove(p + tl, p, n);
|
mch_memmove(p + tl, p, n);
|
||||||
mb_char2bytes(c, p);
|
mb_char2bytes(c, p);
|
||||||
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
|
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
|
||||||
@@ -5955,8 +5955,8 @@ find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
|
|||||||
#ifdef FEAT_MBYTE
|
#ifdef FEAT_MBYTE
|
||||||
if (has_mbyte)
|
if (has_mbyte)
|
||||||
{
|
{
|
||||||
flen = mb_cptr2len(fword + fwordidx[depth]);
|
flen = MB_CPTR2LEN(fword + fwordidx[depth]);
|
||||||
ulen = mb_cptr2len(uword + uwordidx[depth]);
|
ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
@@ -8,3 +8,4 @@
|
|||||||
source test_expr_utf8.vim
|
source test_expr_utf8.vim
|
||||||
source test_matchadd_conceal_utf8.vim
|
source test_matchadd_conceal_utf8.vim
|
||||||
source test_regexp_utf8.vim
|
source test_regexp_utf8.vim
|
||||||
|
source test_source_utf8.vim
|
||||||
|
@@ -92,18 +92,3 @@ func Test_classes_re2()
|
|||||||
call s:classes_test()
|
call s:classes_test()
|
||||||
set re=0
|
set re=0
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
func Test_source_utf8()
|
|
||||||
" check that sourcing a script with 0x80 as second byte works
|
|
||||||
new
|
|
||||||
call setline(1, [':%s/àx/--à1234--/g', ':%s/Àx/--À1234--/g'])
|
|
||||||
write! Xscript
|
|
||||||
bwipe!
|
|
||||||
new
|
|
||||||
call setline(1, [' àx ', ' Àx '])
|
|
||||||
source! Xscript | echo
|
|
||||||
call assert_equal(' --à1234-- ', getline(1))
|
|
||||||
call assert_equal(' --À1234-- ', getline(2))
|
|
||||||
bwipe!
|
|
||||||
call delete('Xscript')
|
|
||||||
endfunc
|
|
||||||
|
33
src/testdir/test_source_utf8.vim
Normal file
33
src/testdir/test_source_utf8.vim
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
" Test the :source! command
|
||||||
|
if !has('multi_byte')
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
|
||||||
|
func Test_source_utf8()
|
||||||
|
" check that sourcing a script with 0x80 as second byte works
|
||||||
|
new
|
||||||
|
call setline(1, [':%s/àx/--à1234--/g', ':%s/Àx/--À1234--/g'])
|
||||||
|
write! Xscript
|
||||||
|
bwipe!
|
||||||
|
new
|
||||||
|
call setline(1, [' àx ', ' Àx '])
|
||||||
|
source! Xscript | echo
|
||||||
|
call assert_equal(' --à1234-- ', getline(1))
|
||||||
|
call assert_equal(' --À1234-- ', getline(2))
|
||||||
|
bwipe!
|
||||||
|
call delete('Xscript')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_source_latin()
|
||||||
|
" check that sourcing a latin1 script with a 0xc0 byte works
|
||||||
|
new
|
||||||
|
call setline(1, ["call feedkeys('r')", "call feedkeys('\xc0', 'xt')"])
|
||||||
|
write! Xscript
|
||||||
|
bwipe!
|
||||||
|
new
|
||||||
|
call setline(1, ['xxx'])
|
||||||
|
source Xscript
|
||||||
|
call assert_equal("\u00c0xx", getline(1))
|
||||||
|
bwipe!
|
||||||
|
call delete('Xscript')
|
||||||
|
endfunc
|
@@ -763,6 +763,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 */
|
||||||
|
/**/
|
||||||
|
2223,
|
||||||
/**/
|
/**/
|
||||||
2222,
|
2222,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user