components/vim/vim72-patches/7.2.080
changeset 198 172fc01ce997
equal deleted inserted replaced
197:fd801ec0737c 198:172fc01ce997
       
     1 To: [email protected]
       
     2 Subject: Patch 7.2.080
       
     3 Fcc: outbox
       
     4 From: Bram Moolenaar <[email protected]>
       
     5 Mime-Version: 1.0
       
     6 Content-Type: text/plain; charset=ISO-8859-1
       
     7 Content-Transfer-Encoding: 8bit
       
     8 ------------
       
     9 
       
    10 Patch 7.2.080
       
    11 Problem:    When typing a composing character just after starting completion
       
    12 	    may access memory before its allocation point. (Dominique Pelle)
       
    13 Solution:   Don't delete before the completion start column.  Add extra checks
       
    14 	    for the offset not being negative.
       
    15 Files:	    src/edit.c
       
    16 
       
    17 
       
    18 *** ../vim-7.2.079/src/edit.c	Wed Aug  6 18:56:55 2008
       
    19 --- src/edit.c	Tue Jan 13 12:05:57 2009
       
    20 ***************
       
    21 *** 147,152 ****
       
    22 --- 147,153 ----
       
    23   static int  ins_compl_bs __ARGS((void));
       
    24   static void ins_compl_new_leader __ARGS((void));
       
    25   static void ins_compl_addleader __ARGS((int c));
       
    26 + static int ins_compl_len __ARGS((void));
       
    27   static void ins_compl_restart __ARGS((void));
       
    28   static void ins_compl_set_original_text __ARGS((char_u *str));
       
    29   static void ins_compl_addfrommatch __ARGS((void));
       
    30 ***************
       
    31 *** 197,203 ****
       
    32   static void mb_replace_pop_ins __ARGS((int cc));
       
    33   #endif
       
    34   static void replace_flush __ARGS((void));
       
    35 ! static void replace_do_bs __ARGS((void));
       
    36   #ifdef FEAT_CINDENT
       
    37   static int cindent_on __ARGS((void));
       
    38   #endif
       
    39 --- 198,205 ----
       
    40   static void mb_replace_pop_ins __ARGS((int cc));
       
    41   #endif
       
    42   static void replace_flush __ARGS((void));
       
    43 ! static void replace_do_bs __ARGS((int limit_col));
       
    44 ! static int del_char_after_col __ARGS((int limit_col));
       
    45   #ifdef FEAT_CINDENT
       
    46   static int cindent_on __ARGS((void));
       
    47   #endif
       
    48 ***************
       
    49 *** 1933,1938 ****
       
    50 --- 1935,1942 ----
       
    51   /*
       
    52    * Backspace the cursor until the given column.  Handles REPLACE and VREPLACE
       
    53    * modes correctly.  May also be used when not in insert mode at all.
       
    54 +  * Will attempt not to go before "col" even when there is a composing
       
    55 +  * character.
       
    56    */
       
    57       void
       
    58   backspace_until_column(col)
       
    59 ***************
       
    60 *** 1942,1954 ****
       
    61       {
       
    62   	curwin->w_cursor.col--;
       
    63   	if (State & REPLACE_FLAG)
       
    64 ! 	    replace_do_bs();
       
    65 ! 	else
       
    66 ! 	    (void)del_char(FALSE);
       
    67       }
       
    68   }
       
    69   #endif
       
    70   
       
    71   #if defined(FEAT_INS_EXPAND) || defined(PROTO)
       
    72   /*
       
    73    * CTRL-X pressed in Insert mode.
       
    74 --- 1946,1994 ----
       
    75       {
       
    76   	curwin->w_cursor.col--;
       
    77   	if (State & REPLACE_FLAG)
       
    78 ! 	    replace_do_bs(col);
       
    79 ! 	else if (!del_char_after_col(col))
       
    80 ! 	    break;
       
    81       }
       
    82   }
       
    83   #endif
       
    84   
       
    85 + /*
       
    86 +  * Like del_char(), but make sure not to go before column "limit_col".
       
    87 +  * Only matters when there are composing characters.
       
    88 +  * Return TRUE when something was deleted.
       
    89 +  */
       
    90 +    static int
       
    91 + del_char_after_col(limit_col)
       
    92 +     int limit_col;
       
    93 + {
       
    94 + #ifdef FEAT_MBYTE
       
    95 +     if (enc_utf8 && limit_col >= 0)
       
    96 +     {
       
    97 + 	int ecol = curwin->w_cursor.col + 1;
       
    98 + 
       
    99 + 	/* Make sure the cursor is at the start of a character, but
       
   100 + 	 * skip forward again when going too far back because of a
       
   101 + 	 * composing character. */
       
   102 + 	mb_adjust_cursor();
       
   103 + 	while (curwin->w_cursor.col < limit_col)
       
   104 + 	{
       
   105 + 	    int l = utf_ptr2len(ml_get_cursor());
       
   106 + 
       
   107 + 	    if (l == 0)  /* end of line */
       
   108 + 		break;
       
   109 + 	    curwin->w_cursor.col += l;
       
   110 + 	}
       
   111 + 	if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
       
   112 + 	    return FALSE;
       
   113 + 	del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE);
       
   114 +     }
       
   115 +     else
       
   116 + #endif
       
   117 + 	(void)del_char(FALSE);
       
   118 +     return TRUE;
       
   119 + }
       
   120 + 
       
   121   #if defined(FEAT_INS_EXPAND) || defined(PROTO)
       
   122   /*
       
   123    * CTRL-X pressed in Insert mode.
       
   124 ***************
       
   125 *** 2418,2424 ****
       
   126   	{
       
   127   	    had_match = (curwin->w_cursor.col > compl_col);
       
   128   	    ins_compl_delete();
       
   129 ! 	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
       
   130   	    ins_redraw(FALSE);
       
   131   
       
   132   	    /* When the match isn't there (to avoid matching itself) remove it
       
   133 --- 2458,2464 ----
       
   134   	{
       
   135   	    had_match = (curwin->w_cursor.col > compl_col);
       
   136   	    ins_compl_delete();
       
   137 ! 	    ins_bytes(compl_leader + ins_compl_len());
       
   138   	    ins_redraw(FALSE);
       
   139   
       
   140   	    /* When the match isn't there (to avoid matching itself) remove it
       
   141 ***************
       
   142 *** 2470,2476 ****
       
   143   	    *p = NUL;
       
   144   	    had_match = (curwin->w_cursor.col > compl_col);
       
   145   	    ins_compl_delete();
       
   146 ! 	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
       
   147   	    ins_redraw(FALSE);
       
   148   
       
   149   	    /* When the match isn't there (to avoid matching itself) remove it
       
   150 --- 2510,2516 ----
       
   151   	    *p = NUL;
       
   152   	    had_match = (curwin->w_cursor.col > compl_col);
       
   153   	    ins_compl_delete();
       
   154 ! 	    ins_bytes(compl_leader + ins_compl_len());
       
   155   	    ins_redraw(FALSE);
       
   156   
       
   157   	    /* When the match isn't there (to avoid matching itself) remove it
       
   158 ***************
       
   159 *** 3209,3215 ****
       
   160   {
       
   161       ins_compl_del_pum();
       
   162       ins_compl_delete();
       
   163 !     ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
       
   164       compl_used_match = FALSE;
       
   165   
       
   166       if (compl_started)
       
   167 --- 3249,3255 ----
       
   168   {
       
   169       ins_compl_del_pum();
       
   170       ins_compl_delete();
       
   171 !     ins_bytes(compl_leader + ins_compl_len());
       
   172       compl_used_match = FALSE;
       
   173   
       
   174       if (compl_started)
       
   175 ***************
       
   176 *** 3264,3269 ****
       
   177 --- 3304,3323 ----
       
   178   }
       
   179   
       
   180   /*
       
   181 +  * Return the length of the completion, from the completion start column to
       
   182 +  * the cursor column.  Making sure it never goes below zero.
       
   183 +  */
       
   184 +     static int
       
   185 + ins_compl_len()
       
   186 + {
       
   187 +     int off = curwin->w_cursor.col - compl_col;
       
   188 + 
       
   189 +     if (off < 0)
       
   190 + 	return 0;
       
   191 +     return off;
       
   192 + }
       
   193 + 
       
   194 + /*
       
   195    * Append one character to the match leader.  May reduce the number of
       
   196    * matches.
       
   197    */
       
   198 ***************
       
   199 *** 3621,3630 ****
       
   200   	    {
       
   201   		ins_compl_delete();
       
   202   		if (compl_leader != NULL)
       
   203 ! 		    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
       
   204   		else if (compl_first_match != NULL)
       
   205 ! 		    ins_bytes(compl_orig_text
       
   206 ! 					  + curwin->w_cursor.col - compl_col);
       
   207   		retval = TRUE;
       
   208   	    }
       
   209   
       
   210 --- 3675,3683 ----
       
   211   	    {
       
   212   		ins_compl_delete();
       
   213   		if (compl_leader != NULL)
       
   214 ! 		    ins_bytes(compl_leader + ins_compl_len());
       
   215   		else if (compl_first_match != NULL)
       
   216 ! 		    ins_bytes(compl_orig_text + ins_compl_len());
       
   217   		retval = TRUE;
       
   218   	    }
       
   219   
       
   220 ***************
       
   221 *** 4256,4262 ****
       
   222       static void
       
   223   ins_compl_insert()
       
   224   {
       
   225 !     ins_bytes(compl_shown_match->cp_str + curwin->w_cursor.col - compl_col);
       
   226       if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
       
   227   	compl_used_match = FALSE;
       
   228       else
       
   229 --- 4309,4315 ----
       
   230       static void
       
   231   ins_compl_insert()
       
   232   {
       
   233 !     ins_bytes(compl_shown_match->cp_str + ins_compl_len());
       
   234       if (compl_shown_match->cp_flags & ORIGINAL_TEXT)
       
   235   	compl_used_match = FALSE;
       
   236       else
       
   237 ***************
       
   238 *** 4425,4431 ****
       
   239   	if (!compl_get_longest || compl_used_match)
       
   240   	    ins_compl_insert();
       
   241   	else
       
   242 ! 	    ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
       
   243       }
       
   244       else
       
   245   	compl_used_match = FALSE;
       
   246 --- 4478,4484 ----
       
   247   	if (!compl_get_longest || compl_used_match)
       
   248   	    ins_compl_insert();
       
   249   	else
       
   250 ! 	    ins_bytes(compl_leader + ins_compl_len());
       
   251       }
       
   252       else
       
   253   	compl_used_match = FALSE;
       
   254 ***************
       
   255 *** 7123,7131 ****
       
   256    * cc == 0: character was inserted, delete it
       
   257    * cc > 0: character was replaced, put cc (first byte of original char) back
       
   258    * and check for more characters to be put back
       
   259    */
       
   260       static void
       
   261 ! replace_do_bs()
       
   262   {
       
   263       int		cc;
       
   264   #ifdef FEAT_VREPLACE
       
   265 --- 7176,7187 ----
       
   266    * cc == 0: character was inserted, delete it
       
   267    * cc > 0: character was replaced, put cc (first byte of original char) back
       
   268    * and check for more characters to be put back
       
   269 +  * When "limit_col" is >= 0, don't delete before this column.  Matters when
       
   270 +  * using composing characters, use del_char_after_col() instead of del_char().
       
   271    */
       
   272       static void
       
   273 ! replace_do_bs(limit_col)
       
   274 !     int		limit_col;
       
   275   {
       
   276       int		cc;
       
   277   #ifdef FEAT_VREPLACE
       
   278 ***************
       
   279 *** 7153,7159 ****
       
   280   #ifdef FEAT_MBYTE
       
   281   	if (has_mbyte)
       
   282   	{
       
   283 ! 	    del_char(FALSE);
       
   284   # ifdef FEAT_VREPLACE
       
   285   	    if (State & VREPLACE_FLAG)
       
   286   		orig_len = (int)STRLEN(ml_get_cursor());
       
   287 --- 7209,7215 ----
       
   288   #ifdef FEAT_MBYTE
       
   289   	if (has_mbyte)
       
   290   	{
       
   291 ! 	    (void)del_char_after_col(limit_col);
       
   292   # ifdef FEAT_VREPLACE
       
   293   	    if (State & VREPLACE_FLAG)
       
   294   		orig_len = (int)STRLEN(ml_get_cursor());
       
   295 ***************
       
   296 *** 7203,7209 ****
       
   297   	changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
       
   298       }
       
   299       else if (cc == 0)
       
   300 ! 	(void)del_char(FALSE);
       
   301   }
       
   302   
       
   303   #ifdef FEAT_CINDENT
       
   304 --- 7259,7265 ----
       
   305   	changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
       
   306       }
       
   307       else if (cc == 0)
       
   308 ! 	(void)del_char_after_col(limit_col);
       
   309   }
       
   310   
       
   311   #ifdef FEAT_CINDENT
       
   312 ***************
       
   313 *** 8239,8245 ****
       
   314   	 * Replace mode */
       
   315   	if (curwin->w_cursor.lnum != Insstart.lnum
       
   316   		|| curwin->w_cursor.col >= Insstart.col)
       
   317 ! 	    replace_do_bs();
       
   318       }
       
   319       else
       
   320   	(void)del_char(FALSE);
       
   321 --- 8295,8301 ----
       
   322   	 * Replace mode */
       
   323   	if (curwin->w_cursor.lnum != Insstart.lnum
       
   324   		|| curwin->w_cursor.col >= Insstart.col)
       
   325 ! 	    replace_do_bs(-1);
       
   326       }
       
   327       else
       
   328   	(void)del_char(FALSE);
       
   329 ***************
       
   330 *** 8556,8562 ****
       
   331   		break;
       
   332   	    }
       
   333   	    if (State & REPLACE_FLAG)
       
   334 ! 		replace_do_bs();
       
   335   	    else
       
   336   	    {
       
   337   #ifdef FEAT_MBYTE
       
   338 --- 8612,8618 ----
       
   339   		break;
       
   340   	    }
       
   341   	    if (State & REPLACE_FLAG)
       
   342 ! 		replace_do_bs(-1);
       
   343   	    else
       
   344   	    {
       
   345   #ifdef FEAT_MBYTE
       
   346 *** ../vim-7.2.079/src/version.c	Tue Jan  6 16:13:42 2009
       
   347 --- src/version.c	Tue Jan 13 12:25:29 2009
       
   348 ***************
       
   349 *** 678,679 ****
       
   350 --- 678,681 ----
       
   351   {   /* Add new patch number below this line */
       
   352 + /**/
       
   353 +     80,
       
   354   /**/
       
   355 
       
   356 -- 
       
   357 At some point in the project somebody will start whining about the need to
       
   358 determine the project "requirements".  This involves interviewing people who
       
   359 don't know what they want but, curiously, know exactly when they need it.
       
   360 				(Scott Adams - The Dilbert principle)
       
   361 
       
   362  /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
       
   363 ///        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
       
   364 \\\        download, build and distribute -- http://www.A-A-P.org        ///
       
   365  \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///