To: [email protected]
Subject: Patch 6.2f.026
Fcc: outbox
From: Bram Moolenaar <[email protected]>
Mime-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 8bit
------------

Patch 6.2f.026
Problem:    When typing new text at the command line, old composing characters
           may be displayed.
Solution:   Don't read composing characters from after the end of the
           text to be displayed.
Files:      src/ex_getln.c, src/mbyte.c, src/message.c, src/proto/mbyte.pro,
           src/screen.c


*** ../vim-6.2f.025/src/ex_getln.c      Mon May 26 22:15:05 2003
--- src/ex_getln.c      Thu May 29 22:45:46 2003
***************
*** 1403,1408 ****
--- 1403,1409 ----
           if (has_mbyte)
           {
               j = (*mb_char2bytes)(c, IObuff);
+               IObuff[j] = NUL;        /* exclude composing chars */
               put_on_cmdline(IObuff, j, TRUE);
           }
           else
***************
*** 2152,2162 ****
               return; /* out of memory */
       }

!       for (j = start; j < len; j += mb_l)
       {
           p = ccline.cmdbuff + j;
!           u8c = utfc_ptr2char(p, &u8c_c1, &u8c_c2);
!           mb_l = (*mb_ptr2len_check)(p);
           if (ARABIC_CHAR(u8c))
           {
               /* Do Arabic shaping. */
--- 2153,2163 ----
               return; /* out of memory */
       }

!       for (j = start; j < start + len; j += mb_l)
       {
           p = ccline.cmdbuff + j;
!           u8c = utfc_ptr2char_len(p, &u8c_c1, &u8c_c2, start + len - j);
!           mb_l = utfc_ptr2len_check_len(p, start + len - j);
           if (ARABIC_CHAR(u8c))
           {
               /* Do Arabic shaping. */
***************
*** 2166,2177 ****
                   pc = prev_c;
                   pc1 = prev_c1;
                   prev_c1 = u8c_c1;
!                   nc = utf_ptr2char(p + mb_l);
               }
               else
               {
                   /* displaying from left to right */
!                   pc = utfc_ptr2char(p + mb_l, &pc1, &dummy);
                   nc = prev_c;
               }
               prev_c = u8c;
--- 2167,2185 ----
                   pc = prev_c;
                   pc1 = prev_c1;
                   prev_c1 = u8c_c1;
!                   if (j + mb_l >= start + len)
!                       nc = NUL;
!                   else
!                       nc = utf_ptr2char(p + mb_l);
               }
               else
               {
                   /* displaying from left to right */
!                   if (j + mb_l >= start + len)
!                       pc = NUL;
!                   else
!                       pc = utfc_ptr2char_len(p + mb_l, &pc1, &dummy,
!                                                     start + len - j - mb_l);
                   nc = prev_c;
               }
               prev_c = u8c;
*** ../vim-6.2f.025/src/mbyte.c Mon May 26 22:15:06 2003
--- src/mbyte.c Thu May 29 22:51:54 2003
***************
*** 1324,1329 ****
--- 1324,1369 ----
 }

 /*
+  * Convert a UTF-8 byte string to a wide chararacter.  Also get up to two
+  * composing characters.  Use no more than p[maxlen].
+  */
+     int
+ utfc_ptr2char_len(p, p1, p2, maxlen)
+     char_u    *p;
+     int               *p1;    /* return: first composing char or 0 */
+     int               *p2;    /* return: second composing char or 0 */
+     int               maxlen;
+ {
+     int               len;
+     int               c;
+     int               cc;
+
+     c = utf_ptr2char(p);
+     len = utf_ptr2len_check_len(p, maxlen);
+     /* Only accept a composing char when the first char isn't illegal. */
+     if ((len > 1 || *p < 0x80)
+           && len < maxlen
+           && p[len] >= 0x80
+           && UTF_COMPOSINGLIKE(p, p + len))
+     {
+       *p1 = utf_ptr2char(p + len);
+       len += utf_ptr2len_check_len(p + len, maxlen - len);
+       if (len < maxlen
+               && p[len] >= 0x80
+               && utf_iscomposing(cc = utf_ptr2char(p + len)))
+           *p2 = cc;
+       else
+           *p2 = 0;
+     }
+     else
+     {
+       *p1 = 0;
+       *p2 = 0;
+     }
+     return c;
+ }
+
+ /*
  * Convert the character at screen position "off" to a sequence of bytes.
  * Includes the composing characters.
  * "buf" must at least have the length MB_MAXBYTES.
***************
*** 1448,1454 ****
     }
 }

- # if defined(FEAT_GUI_W32) || defined(PROTO)
 /*
  * Return the number of bytes the UTF-8 encoding of the character at "p[size]"
  * takes.  This includes following composing characters.
--- 1488,1493 ----
***************
*** 1459,1464 ****
--- 1498,1506 ----
     int               size;
 {
     int               len;
+ #ifdef FEAT_ARABIC
+     int               prevlen;
+ #endif

     if (*p == NUL)
       return 0;
***************
*** 1476,1492 ****
      * Check for composing characters.  We can handle only the first two, but
      * skip all of them (otherwise the cursor would get stuck).
      */
     while (len < size)
     {
!       if (p[len] < 0x80 || !utf_iscomposing(utf_ptr2char(p + len)))
           break;

       /* Skip over composing char */
       len += utf_ptr2len_check_len(p + len, size - len);
     }
     return len;
 }
- # endif

 /*
  * Return the number of bytes the UTF-8 encoding of character "c" takes.
--- 1518,1539 ----
      * Check for composing characters.  We can handle only the first two, but
      * skip all of them (otherwise the cursor would get stuck).
      */
+ #ifdef FEAT_ARABIC
+     prevlen = 0;
+ #endif
     while (len < size)
     {
!       if (p[len] < 0x80 || !UTF_COMPOSINGLIKE(p + prevlen, p + len))
           break;

       /* Skip over composing char */
+ #ifdef FEAT_ARABIC
+       prevlen = len;
+ #endif
       len += utf_ptr2len_check_len(p + len, size - len);
     }
     return len;
 }

 /*
  * Return the number of bytes the UTF-8 encoding of character "c" takes.
*** ../vim-6.2f.025/src/message.c       Mon May 26 22:58:41 2003
--- src/message.c       Thu May 29 22:50:31 2003
***************
*** 1179,1185 ****
     while (--len >= 0)
     {
 #ifdef FEAT_MBYTE
!       if (has_mbyte && (mb_l = (*mb_ptr2len_check)(str)) > 1)
       {
           c = (*mb_ptr2char)(str);
           if (vim_isprintc(c))
--- 1179,1190 ----
     while (--len >= 0)
     {
 #ifdef FEAT_MBYTE
!       if (enc_utf8)
!           /* Don't include composing chars after the end. */
!           mb_l = utfc_ptr2len_check_len(str, len + 1);
!       else if (has_mbyte)
!           mb_l = (*mb_ptr2len_check)(str);
!       if (has_mbyte && mb_l > 1)
       {
           c = (*mb_ptr2char)(str);
           if (vim_isprintc(c))
***************
*** 2000,2006 ****
           if (has_mbyte)
           {
               cw = (*mb_ptr2cells)(s);
!               l = (*mb_ptr2len_check)(s);
           }
           else
           {
--- 2005,2015 ----
           if (has_mbyte)
           {
               cw = (*mb_ptr2cells)(s);
!               if (enc_utf8 && maxlen >= 0)
!                   /* avoid including composing chars after the end */
!                   l = utfc_ptr2len_check_len(s, (int)((str + maxlen) - s));
!               else
!                   l = (*mb_ptr2len_check)(s);
           }
           else
           {
*** ../vim-6.2f.025/src/proto/mbyte.pro Mon May 26 22:15:05 2003
--- src/proto/mbyte.pro Thu May 29 22:36:12 2003
***************
*** 22,27 ****
--- 22,28 ----
 int arabic_maycombine __ARGS((int two));
 int utf_composinglike __ARGS((char_u *p1, char_u *p2));
 int utfc_ptr2char __ARGS((char_u *p, int *p1, int *p2));
+ int utfc_ptr2char_len __ARGS((char_u *p, int *p1, int *p2, int maxlen));
 int utfc_char2bytes __ARGS((int off, char_u *buf));
 int utf_ptr2len_check __ARGS((char_u *p));
 int utf_byte2len __ARGS((int b));
*** ../vim-6.2f.025/src/screen.c        Mon May 26 22:15:06 2003
--- src/screen.c        Thu May 29 22:55:37 2003
***************
*** 5395,5408 ****
       /* check if this is the first byte of a multibyte */
       if (has_mbyte)
       {
!           mbyte_blen = (*mb_ptr2len_check)(ptr);
           if (enc_dbcs == DBCS_JPNU && c == 0x8e)
               mbyte_cells = 1;
           else if (enc_dbcs != 0)
               mbyte_cells = mbyte_blen;
           else        /* enc_utf8 */
           {
!               u8c = utfc_ptr2char(ptr, &u8c_c1, &u8c_c2);
               mbyte_cells = utf_char2cells(u8c);
               /* Non-BMP character: display as ? or fullwidth ?. */
               if (u8c >= 0x10000)
--- 5395,5416 ----
       /* check if this is the first byte of a multibyte */
       if (has_mbyte)
       {
!           if (enc_utf8 && len > 0)
!               mbyte_blen = utfc_ptr2len_check_len(ptr,
!                                                  (int)((text + len) - ptr));
!           else
!               mbyte_blen = (*mb_ptr2len_check)(ptr);
           if (enc_dbcs == DBCS_JPNU && c == 0x8e)
               mbyte_cells = 1;
           else if (enc_dbcs != 0)
               mbyte_cells = mbyte_blen;
           else        /* enc_utf8 */
           {
!               if (len >= 0)
!                   u8c = utfc_ptr2char_len(ptr, &u8c_c1, &u8c_c2,
!                                                  (int)((text + len) - ptr));
!               else
!                   u8c = utfc_ptr2char(ptr, &u8c_c1, &u8c_c2);
               mbyte_cells = utf_char2cells(u8c);
               /* Non-BMP character: display as ? or fullwidth ?. */
               if (u8c >= 0x10000)
*** ../vim-6.2f.025/src/version.c       Thu May 29 21:06:44 2003
--- src/version.c       Thu May 29 22:37:58 2003
***************
*** 632,633 ****
--- 632,635 ----
 {   /* Add new patch number below this line */
+ /**/
+     26,
 /**/

--
How To Keep A Healthy Level Of Insanity:
3. Every time someone asks you to do something, ask if they want fries
  with that.

/// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///          Creator of Vim - Vi IMproved -- http://www.Vim.org          \\\
\\\              Project leader for A-A-P -- http://www.A-A-P.org        ///
\\\     Help AIDS victims, buy at Amazon -- http://ICCF.nl/click1.html ///