4 From: Bram Moolenaar <Bram@moolenaar.net>
6 Content-Type: text/plain; charset=ISO-8859-1
7 Content-Transfer-Encoding: 8bit
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.
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
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));
32 static void mb_replace_pop_ins __ARGS((int cc));
34 static void replace_flush __ARGS((void));
35 ! static void replace_do_bs __ARGS((void));
37 static int cindent_on __ARGS((void));
40 static void mb_replace_pop_ins __ARGS((int cc));
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));
46 static int cindent_on __ARGS((void));
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
58 backspace_until_column(col)
62 curwin->w_cursor.col--;
63 if (State & REPLACE_FLAG)
66 ! (void)del_char(FALSE);
71 #if defined(FEAT_INS_EXPAND) || defined(PROTO)
73 * CTRL-X pressed in Insert mode.
76 curwin->w_cursor.col--;
77 if (State & REPLACE_FLAG)
79 ! else if (!del_char_after_col(col))
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.
91 + del_char_after_col(limit_col)
95 + if (enc_utf8 && limit_col >= 0)
97 + int ecol = curwin->w_cursor.col + 1;
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)
105 + int l = utf_ptr2len(ml_get_cursor());
107 + if (l == 0) /* end of line */
109 + curwin->w_cursor.col += l;
111 + if (*ml_get_cursor() == NUL || curwin->w_cursor.col == ecol)
113 + del_bytes((long)(ecol - curwin->w_cursor.col), FALSE, TRUE);
117 + (void)del_char(FALSE);
121 #if defined(FEAT_INS_EXPAND) || defined(PROTO)
123 * CTRL-X pressed in Insert mode.
127 had_match = (curwin->w_cursor.col > compl_col);
129 ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
132 /* When the match isn't there (to avoid matching itself) remove it
135 had_match = (curwin->w_cursor.col > compl_col);
137 ! ins_bytes(compl_leader + ins_compl_len());
140 /* When the match isn't there (to avoid matching itself) remove it
144 had_match = (curwin->w_cursor.col > compl_col);
146 ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
149 /* When the match isn't there (to avoid matching itself) remove it
152 had_match = (curwin->w_cursor.col > compl_col);
154 ! ins_bytes(compl_leader + ins_compl_len());
157 /* When the match isn't there (to avoid matching itself) remove it
163 ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
164 compl_used_match = FALSE;
171 ! ins_bytes(compl_leader + ins_compl_len());
172 compl_used_match = FALSE;
181 + * Return the length of the completion, from the completion start column to
182 + * the cursor column. Making sure it never goes below zero.
187 + int off = curwin->w_cursor.col - compl_col;
195 * Append one character to the match leader. May reduce the number of
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);
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());
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;
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;
239 if (!compl_get_longest || compl_used_match)
242 ! ins_bytes(compl_leader + curwin->w_cursor.col - compl_col);
245 compl_used_match = FALSE;
247 if (!compl_get_longest || compl_used_match)
250 ! ins_bytes(compl_leader + ins_compl_len());
253 compl_used_match = FALSE;
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
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().
273 ! replace_do_bs(limit_col)
284 # ifdef FEAT_VREPLACE
285 if (State & VREPLACE_FLAG)
286 orig_len = (int)STRLEN(ml_get_cursor());
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());
297 changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
300 ! (void)del_char(FALSE);
305 changed_bytes(curwin->w_cursor.lnum, curwin->w_cursor.col);
308 ! (void)del_char_after_col(limit_col);
315 if (curwin->w_cursor.lnum != Insstart.lnum
316 || curwin->w_cursor.col >= Insstart.col)
320 (void)del_char(FALSE);
323 if (curwin->w_cursor.lnum != Insstart.lnum
324 || curwin->w_cursor.col >= Insstart.col)
328 (void)del_char(FALSE);
333 if (State & REPLACE_FLAG)
341 if (State & REPLACE_FLAG)
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
351 { /* Add new patch number below this line */
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)
362 /// Bram Moolenaar -- Bram@Moolenaar.net -- 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 ///