1
0
forked from aniani/vim

patch 8.2.4120: block insert goes over the end of the line

Problem:    Block insert goes over the end of the line.
Solution:   Handle invalid byte better.  Fix inserting the wrong text.
This commit is contained in:
Bram Moolenaar
2022-01-17 17:30:21 +00:00
parent e8741a73e2
commit 9f8c304c8a
3 changed files with 37 additions and 14 deletions

View File

@@ -536,24 +536,29 @@ block_insert(
if (b_insert) if (b_insert)
{ {
off = (*mb_head_off)(oldp, oldp + offset + spaces); off = (*mb_head_off)(oldp, oldp + offset + spaces);
spaces -= off;
count -= off;
} }
else else
{ {
off = (*mb_off_next)(oldp, oldp + offset); // spaces fill the gap, the character that's at the edge moves
offset += off; // right
off = (*mb_head_off)(oldp, oldp + offset);
offset -= off;
} }
spaces -= off;
count -= off;
} }
if (spaces < 0) // can happen when the cursor was moved if (spaces < 0) // can happen when the cursor was moved
spaces = 0; spaces = 0;
newp = alloc(STRLEN(oldp) + s_len + count + 1); // Make sure the allocated size matches what is actually copied below.
newp = alloc(STRLEN(oldp) + spaces + s_len
+ (spaces > 0 && !bdp->is_short ? ts_val - spaces : 0)
+ count + 1);
if (newp == NULL) if (newp == NULL)
continue; continue;
// copy up to shifted part // copy up to shifted part
mch_memmove(newp, oldp, (size_t)(offset)); mch_memmove(newp, oldp, (size_t)offset);
oldp += offset; oldp += offset;
// insert pre-padding // insert pre-padding
@@ -564,14 +569,21 @@ block_insert(
mch_memmove(newp + startcol, s, (size_t)s_len); mch_memmove(newp + startcol, s, (size_t)s_len);
offset += s_len; offset += s_len;
if (spaces && !bdp->is_short) if (spaces > 0 && !bdp->is_short)
{ {
// insert post-padding if (*oldp == TAB)
vim_memset(newp + offset + spaces, ' ', (size_t)(ts_val - spaces)); {
// We're splitting a TAB, don't copy it. // insert post-padding
oldp++; vim_memset(newp + offset + spaces, ' ',
// We allowed for that TAB, remember this now (size_t)(ts_val - spaces));
count++; // we're splitting a TAB, don't copy it
oldp++;
// We allowed for that TAB, remember this now
count++;
}
else
// Not a TAB, no extra spaces
count = spaces;
} }
if (spaces > 0) if (spaces > 0)
@@ -1598,7 +1610,7 @@ op_insert(oparg_T *oap, long count1)
oap->start_vcol = t; oap->start_vcol = t;
} }
else if (oap->op_type == OP_APPEND else if (oap->op_type == OP_APPEND
&& oap->end.col + oap->end.coladd && oap->start.col + oap->start.coladd
>= curbuf->b_op_start_orig.col >= curbuf->b_op_start_orig.col
+ curbuf->b_op_start_orig.coladd) + curbuf->b_op_start_orig.coladd)
{ {

View File

@@ -1278,6 +1278,15 @@ func Test_visual_block_ctrl_w_f()
au! BufNew au! BufNew
endfunc endfunc
func Test_visual_block_append_invalid_char()
" this was going over the end of the line
new
call setline(1, [' let xxx', 'xxxxxˆ', 'xxxxxxxxxxx'])
exe "normal 0\<C-V>jjA-\<Esc>"
call assert_equal([' - let xxx', 'xxxxx -ˆ', 'xxxxxxxx-xxx'], getline(1, 3))
bwipe!
endfunc
func Test_visual_reselect_with_count() func Test_visual_reselect_with_count()
" this was causing an illegal memory access " this was causing an illegal memory access
let lines =<< trim END let lines =<< trim END

View File

@@ -750,6 +750,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
4120,
/**/ /**/
4119, 4119,
/**/ /**/