Patch 7.4.2223
Problem: Buffer overflow when using latin1 character with feedkeys().
Solution: Check for an illegal character. Add a test.
Files: src/testdir/test_regexp_utf8.vim, src/testdir/test_source_utf8.vim,
src/testdir/test_alot_utf8.vim, src/Makefile, src/getchar.c,
src/macros.h, src/evalfunc.c, src/os_unix.c, src/os_win32.c,
src/spell.c
*** ../vim-7.4.2222/src/testdir/test_regexp_utf8.vim 2016-08-16
22:50:50.758254682 +0200
--- src/testdir/test_regexp_utf8.vim 2016-08-17 20:17:41.702422218 +0200
***************
*** 92,109 ****
call s:classes_test()
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
--- 92,94 ----
*** ../vim-7.4.2222/src/testdir/test_source_utf8.vim 2016-08-17
21:30:50.354447196 +0200
--- src/testdir/test_source_utf8.vim 2016-08-17 21:28:17.083826957 +0200
***************
*** 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
*** ../vim-7.4.2222/src/testdir/test_alot_utf8.vim 2016-07-21
20:33:28.835262339 +0200
--- src/testdir/test_alot_utf8.vim 2016-08-17 21:29:14.823307132 +0200
***************
*** 8,10 ****
--- 8,11 ----
source test_expr_utf8.vim
source test_matchadd_conceal_utf8.vim
source test_regexp_utf8.vim
+ source test_source_utf8.vim
*** ../vim-7.4.2222/src/Makefile 2016-08-14 15:31:53.353671912 +0200
--- src/Makefile 2016-08-17 21:29:25.523210804 +0200
***************
*** 2114,2119 ****
--- 2114,2120 ----
test_set \
test_signs \
test_sort \
+ test_source_utf8 \
test_startup \
test_startup_utf8 \
test_stat \
*** ../vim-7.4.2222/src/getchar.c 2016-08-16 22:50:50.754254718 +0200
--- src/getchar.c 2016-08-17 21:06:50.959528112 +0200
***************
*** 4658,4665 ****
char_u *res;
char_u *s, *d;
! /* Need a buffer to hold up to three times as much. */
! res = alloc((unsigned)(STRLEN(p) * 3) + 1);
if (res != NULL)
{
d = res;
--- 4658,4673 ----
char_u *res;
char_u *s, *d;
! /* 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 */
! res = alloc((unsigned)(STRLEN(p) *
! #ifdef FEAT_MBYTE
! 4
! #else
! 3
! #endif
! ) + 1);
if (res != NULL)
{
d = res;
***************
*** 4674,4695 ****
}
else
{
- #ifdef FEAT_MBYTE
- int len = mb_char2len(PTR2CHAR(s));
- int len2 = mb_ptr2len(s);
- #endif
/* Add character, possibly multi-byte to destination, escaping
! * CSI and K_SPECIAL. */
d = add_char2buf(PTR2CHAR(s), d);
! #ifdef FEAT_MBYTE
! 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;
--- 4682,4691 ----
}
else
{
/* 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);
! s += MB_CPTR2LEN(s);
}
}
*d = NUL;
*** ../vim-7.4.2222/src/macros.h 2016-07-17 20:37:38.235378864 +0200
--- src/macros.h 2016-08-17 21:08:28.650636119 +0200
***************
*** 274,280 ****
/* 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
/* get length of multi-byte char, not including composing chars */
! # 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_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
--- 274,280 ----
/* 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
/* get length of multi-byte char, not including composing chars */
! # 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_CHARLEN(p) (has_mbyte ? mb_charlen(p) : (int)STRLEN(p))
***************
*** 282,287 ****
--- 282,288 ----
# define PTR2CHAR(p) (has_mbyte ? mb_ptr2char(p) : (int)*(p))
#else
# define MB_PTR2LEN(p) 1
+ # define MB_CPTR2LEN(p) 1
# define mb_ptr_adv(p) ++p
# define mb_cptr_adv(p) ++p
# define mb_ptr_back(s, p) --p
*** ../vim-7.4.2222/src/evalfunc.c 2016-08-15 22:16:21.557888355 +0200
--- src/evalfunc.c 2016-08-17 21:07:28.759182915 +0200
***************
*** 11166,11172 ****
break;
}
--charidx;
! byteidx += mb_cptr2len(str + byteidx);
}
}
#else
--- 11166,11172 ----
break;
}
--charidx;
! byteidx += MB_CPTR2LEN(str + byteidx);
}
}
#else
***************
*** 11326,11332 ****
if (nchar > 0)
while (nchar > 0 && nbyte < slen)
{
! nbyte += mb_cptr2len(p + nbyte);
--nchar;
}
else
--- 11326,11332 ----
if (nchar > 0)
while (nchar > 0 && nbyte < slen)
{
! nbyte += MB_CPTR2LEN(p + nbyte);
--nchar;
}
else
***************
*** 11341,11347 ****
if (off < 0)
len += 1;
else
! len += mb_cptr2len(p + off);
--charlen;
}
}
--- 11341,11347 ----
if (off < 0)
len += 1;
else
! len += MB_CPTR2LEN(p + off);
--charlen;
}
}
*** ../vim-7.4.2222/src/os_unix.c 2016-08-14 18:23:16.755039539 +0200
--- src/os_unix.c 2016-08-17 21:07:35.983116953 +0200
***************
*** 4806,4812 ****
* round. */
for (p = buffer; p < buffer + len; p += l)
{
! l = mb_cptr2len(p);
if (l == 0)
l = 1; /* NUL byte? */
else if (MB_BYTE2LEN(*p) != l)
--- 4806,4812 ----
* round. */
for (p = buffer; p < buffer + len; p += l)
{
! l = MB_CPTR2LEN(p);
if (l == 0)
l = 1; /* NUL byte? */
else if (MB_BYTE2LEN(*p) != l)
*** ../vim-7.4.2222/src/os_win32.c 2016-08-04 22:00:07.756346935 +0200
--- src/os_win32.c 2016-08-17 21:07:48.938998658 +0200
***************
*** 4370,4376 ****
* round. */
for (p = buffer; p < buffer + len; p += l)
{
! l = mb_cptr2len(p);
if (l == 0)
l = 1; /* NUL byte? */
else if (MB_BYTE2LEN(*p) != l)
--- 4370,4376 ----
* round. */
for (p = buffer; p < buffer + len; p += l)
{
! l = MB_CPTR2LEN(p);
if (l == 0)
l = 1; /* NUL byte? */
else if (MB_BYTE2LEN(*p) != l)
*** ../vim-7.4.2222/src/spell.c 2016-07-24 21:58:39.716057524 +0200
--- src/spell.c 2016-08-17 21:08:21.318703048 +0200
***************
*** 5379,5385 ****
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = mb_cptr2len(p);
c = mb_ptr2char(p);
if (p[n] == NUL)
c2 = NUL;
--- 5379,5385 ----
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
if (p[n] == NUL)
c2 = NUL;
***************
*** 5477,5485 ****
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = mb_cptr2len(p);
c = mb_ptr2char(p);
! 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 */
--- 5477,5485 ----
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
! 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 */
***************
*** 5596,5605 ****
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = mb_cptr2len(p);
c = mb_ptr2char(p);
! fl = mb_cptr2len(p + n);
! fl += mb_cptr2len(p + n + fl);
mch_memmove(p, p + n, fl);
mb_char2bytes(c, p + fl);
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
--- 5596,5605 ----
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = MB_CPTR2LEN(p);
c = mb_ptr2char(p);
! fl = MB_CPTR2LEN(p + n);
! fl += MB_CPTR2LEN(p + n + fl);
mch_memmove(p, p + n, fl);
mb_char2bytes(c, p + fl);
stack[depth].ts_fidxtry = sp->ts_fidx + n + fl;
***************
*** 5661,5670 ****
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = mb_cptr2len(p);
! n += mb_cptr2len(p + n);
c = mb_ptr2char(p + n);
! tl = mb_cptr2len(p + n);
mch_memmove(p + tl, p, n);
mb_char2bytes(c, p);
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
--- 5661,5670 ----
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! n = MB_CPTR2LEN(p);
! n += MB_CPTR2LEN(p + n);
c = mb_ptr2char(p + n);
! tl = MB_CPTR2LEN(p + n);
mch_memmove(p + tl, p, n);
mb_char2bytes(c, p);
stack[depth].ts_fidxtry = sp->ts_fidx + n + tl;
***************
*** 5955,5962 ****
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! flen = mb_cptr2len(fword + fwordidx[depth]);
! ulen = mb_cptr2len(uword + uwordidx[depth]);
}
else
#endif
--- 5955,5962 ----
#ifdef FEAT_MBYTE
if (has_mbyte)
{
! flen = MB_CPTR2LEN(fword + fwordidx[depth]);
! ulen = MB_CPTR2LEN(uword + uwordidx[depth]);
}
else
#endif
*** ../vim-7.4.2222/src/version.c 2016-08-16 22:50:50.758254682 +0200
--- src/version.c 2016-08-17 20:59:12.907717106 +0200
***************
*** 765,766 ****
--- 765,768 ----
{ /* Add new patch number below this line */
+ /**/
+ 2223,
/**/
--
How To Keep A Healthy Level Of Insanity:
17. When the money comes out the ATM, scream "I won!, I won! 3rd
time this week!!!!!"
/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///
--
--
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
---
You received this message because you are subscribed to the Google Groups
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.