mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
vim-patch:7.4.2223
Problem: Buffer overflow when using latin1 character with feedkeys().
Solution: Check for an illegal character. Add a test.
d3c907b5d2
This commit is contained in:
parent
eaf1f9b9dc
commit
2ed2b1d505
@ -16932,7 +16932,7 @@ static void f_strgetchar(typval_T *argvars, typval_T *rettv, FunPtr fptr)
|
||||
break;
|
||||
}
|
||||
charidx--;
|
||||
byteidx += mb_cptr2len(str + byteidx);
|
||||
byteidx += MB_CPTR2LEN(str + byteidx);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -17054,7 +17054,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
|
||||
if (!error) {
|
||||
if (nchar > 0) {
|
||||
while (nchar > 0 && nbyte < slen) {
|
||||
nbyte += mb_cptr2len(p + nbyte);
|
||||
nbyte += MB_CPTR2LEN(p + nbyte);
|
||||
nchar--;
|
||||
}
|
||||
} else {
|
||||
@ -17069,7 +17069,7 @@ static void f_strcharpart(typval_T *argvars, typval_T *rettv, FunPtr fptr) {
|
||||
if (off < 0) {
|
||||
len += 1;
|
||||
} else {
|
||||
len += mb_cptr2len(p + off);
|
||||
len += MB_CPTR2LEN(p + off);
|
||||
}
|
||||
charlen--;
|
||||
}
|
||||
|
@ -3746,8 +3746,10 @@ eval_map_expr (
|
||||
*/
|
||||
char_u *vim_strsave_escape_csi(char_u *p)
|
||||
{
|
||||
/* Need a buffer to hold up to three times as much. */
|
||||
char_u *res = xmalloc(STRLEN(p) * 3 + 1);
|
||||
// Need a buffer to hold up to three times as much. Four in case of an
|
||||
// illegal utf-8 byte:
|
||||
// 0xc0 -> 0xc3 - 0x80 -> 0xc3 K_SPECIAL KS_SPECIAL KE_FILLER
|
||||
char_u *res = xmalloc(STRLEN(p) * 4 + 1);
|
||||
char_u *d = res;
|
||||
for (char_u *s = p; *s != NUL; ) {
|
||||
if (s[0] == K_SPECIAL && s[1] != NUL && s[2] != NUL) {
|
||||
@ -3756,17 +3758,10 @@ char_u *vim_strsave_escape_csi(char_u *p)
|
||||
*d++ = *s++;
|
||||
*d++ = *s++;
|
||||
} else {
|
||||
int len = mb_char2len(PTR2CHAR(s));
|
||||
int len2 = mb_ptr2len(s);
|
||||
/* Add character, possibly multi-byte to destination, escaping
|
||||
* CSI and K_SPECIAL. */
|
||||
// Add character, possibly multi-byte to destination, escaping
|
||||
// CSI and K_SPECIAL. Be careful, it can be an illegal byte!
|
||||
d = add_char2buf(PTR2CHAR(s), d);
|
||||
while (len < len2) {
|
||||
/* add following combining char */
|
||||
d = add_char2buf(PTR2CHAR(s + len), d);
|
||||
len += mb_char2len(PTR2CHAR(s + len));
|
||||
}
|
||||
mb_ptr_adv(s);
|
||||
s += MB_CPTR2LEN(s);
|
||||
}
|
||||
}
|
||||
*d = NUL;
|
||||
|
@ -138,7 +138,7 @@
|
||||
// Backup multi-byte pointer. Only use with "p" > "s" !
|
||||
# define mb_ptr_back(s, p) (p -= mb_head_off((char_u *)s, (char_u *)p - 1) + 1)
|
||||
// get length of multi-byte char, not including composing chars
|
||||
# define mb_cptr2len(p) utf_ptr2len(p)
|
||||
# define MB_CPTR2LEN(p) utf_ptr2len(p)
|
||||
|
||||
# define MB_COPY_CHAR(f, t) mb_copy_char((const char_u **)(&f), &t);
|
||||
|
||||
|
@ -4507,7 +4507,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
||||
}
|
||||
|
||||
if (has_mbyte) {
|
||||
n = mb_cptr2len(p);
|
||||
n = MB_CPTR2LEN(p);
|
||||
c = mb_ptr2char(p);
|
||||
if (p[n] == NUL)
|
||||
c2 = NUL;
|
||||
@ -4584,9 +4584,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
||||
// "fword" here, it's changed back afterwards at STATE_UNSWAP3.
|
||||
p = fword + sp->ts_fidx;
|
||||
if (has_mbyte) {
|
||||
n = mb_cptr2len(p);
|
||||
n = MB_CPTR2LEN(p);
|
||||
c = mb_ptr2char(p);
|
||||
fl = mb_cptr2len(p + n);
|
||||
fl = MB_CPTR2LEN(p + n);
|
||||
c2 = mb_ptr2char(p + n);
|
||||
if (!soundfold && !spell_iswordp(p + n + fl, curwin))
|
||||
c3 = c; // don't swap non-word char
|
||||
@ -4682,10 +4682,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
||||
++depth;
|
||||
p = fword + sp->ts_fidx;
|
||||
if (has_mbyte) {
|
||||
n = mb_cptr2len(p);
|
||||
n = MB_CPTR2LEN(p);
|
||||
c = mb_ptr2char(p);
|
||||
fl = mb_cptr2len(p + n);
|
||||
fl += mb_cptr2len(p + n + fl);
|
||||
fl = MB_CPTR2LEN(p + n);
|
||||
fl += MB_CPTR2LEN(p + n + fl);
|
||||
memmove(p, p + n, fl);
|
||||
mb_char2bytes(c, p + fl);
|
||||
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
|
||||
@ -4734,10 +4734,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
|
||||
++depth;
|
||||
p = fword + sp->ts_fidx;
|
||||
if (has_mbyte) {
|
||||
n = mb_cptr2len(p);
|
||||
n += mb_cptr2len(p + n);
|
||||
n = MB_CPTR2LEN(p);
|
||||
n += MB_CPTR2LEN(p + n);
|
||||
c = mb_ptr2char(p + n);
|
||||
tl = mb_cptr2len(p + n);
|
||||
tl = MB_CPTR2LEN(p + n);
|
||||
memmove(p + tl, p, n);
|
||||
mb_char2bytes(c, p);
|
||||
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
|
||||
@ -4980,8 +4980,8 @@ static void find_keepcap_word(slang_T *slang, char_u *fword, char_u *kword)
|
||||
// round[depth] == 1: Try using the folded-case character.
|
||||
// round[depth] == 2: Try using the upper-case character.
|
||||
if (has_mbyte) {
|
||||
flen = mb_cptr2len(fword + fwordidx[depth]);
|
||||
ulen = mb_cptr2len(uword + uwordidx[depth]);
|
||||
flen = MB_CPTR2LEN(fword + fwordidx[depth]);
|
||||
ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
|
||||
} else
|
||||
ulen = flen = 1;
|
||||
if (round[depth] == 1) {
|
||||
|
@ -21,6 +21,7 @@ source test_options.vim
|
||||
source test_partial.vim
|
||||
source test_popup.vim
|
||||
source test_regexp_utf8.vim
|
||||
source test_source_utf8.vim
|
||||
source test_statusline.vim
|
||||
source test_syn_attr.vim
|
||||
source test_tabline.vim
|
||||
|
@ -90,21 +90,6 @@ func Test_classes_re2()
|
||||
set re=0
|
||||
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
|
||||
|
||||
func Test_recursive_substitute()
|
||||
new
|
||||
s/^/\=execute("s#^##gn")
|
||||
|
33
src/nvim/testdir/test_source_utf8.vim
Normal file
33
src/nvim/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
|
@ -217,7 +217,7 @@ static int included_patches[] = {
|
||||
2226,
|
||||
2225,
|
||||
// 2224,
|
||||
// 2223,
|
||||
2223,
|
||||
2222,
|
||||
// 2221,
|
||||
2220,
|
||||
|
Loading…
Reference in New Issue
Block a user