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 -- b...@moolenaar.net -- 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 vim_dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Raspunde prin e-mail lui