From 57df9e8a9f9ae1aafdde9b86b10ad907627a87dc Mon Sep 17 00:00:00 2001 From: Bram Moolenaar Date: Thu, 20 Jan 2022 12:10:48 +0000 Subject: [PATCH] patch 8.2.4151: reading beyond the end of a line Problem: Reading beyond the end of a line. Solution: For block insert only use the offset for correcting the length. --- src/ops.c | 19 ++----------------- src/testdir/test_visual.vim | 9 +++++++++ src/version.c | 2 ++ 3 files changed, 13 insertions(+), 17 deletions(-) Backport: * In Debian, this patch got swapped with CVE-2022-0261 aka 9f8c304c8a390ade133bac29963dc8e56ab14cbc. * We also backport the spaces check from 4067bd3604215b48e4b4201e28f9e401b08418e4, see #1023818. * We also backport the expected test output from fc6ccebea668c49e9e617e0657421b6a8ed9df1e. * Replace expr-.. by expr-. diff --git a/src/ops.c b/src/ops.c index a9968024901e..e0fa344d8ee6 100644 --- a/src/ops.c +++ b/src/ops.c @@ -629,24 +629,12 @@ block_insert( } if (has_mbyte && spaces > 0) - { - int off; + /* avoid copying part of a multi-byte character */ + offset -= (*mb_head_off)(oldp, oldp + offset); - /* Avoid starting halfway a multi-byte character. */ - if (b_insert) - { - off = (*mb_head_off)(oldp, oldp + offset + spaces); - spaces -= off; - count -= off; - } - else - { - // spaces fill the gap, the character that's at the edge moves - // right - off = (*mb_head_off)(oldp, oldp + offset); - offset -= off; - } - } + if (spaces < 0) // can happen when the cursor was moved + spaces = 0; + // Make sure the allocated size matches what is actually copied below. newp = alloc_check((unsigned)(STRLEN(oldp)) + spaces + s_len + (spaces > 0 && !bdp->is_short ? p_ts - spaces : 0) diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim index b438fa1e66c6..a187aa8e085e 100644 --- a/src/testdir/test_visual.vim +++ b/src/testdir/test_visual.vim @@ -417,6 +417,15 @@ bwipe! endfunc +func Test_visual_block_insert_round_off() + new + " The number of characters are tuned to fill a 4096 byte allocated block, + " so that valgrind reports going over the end. + call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)]) + exe "normal gg0\GI" . repeat('0', 1320) . "\" + bwipe! +endfunc + " CVE-2022-0361 func Test_visual_ex_copy_line() new diff --git a/src/testdir/test_utf8.vim b/src/testdir/test_utf8.vim index 0210ce63c..862e73b9a 100644 --- a/src/testdir/test_utf8.vim +++ b/src/testdir/test_utf8.vim @@ -6,7 +6,7 @@ func Test_visual_block_insert() new call setline(1, ["aaa", "あああ", "bbb"]) exe ":norm! gg0l\jjIx\" - call assert_equal(['axaa', 'xあああ', 'bxbb'], getline(1, '$')) + call assert_equal(['axaa', ' xあああ', 'bxbb'], getline(1, '$')) bwipeout! endfunc diff --git a/src/version.c b/src/version.c index 53f1619f94d4..227eaa958e2b 100644 --- a/src/version.c +++ b/src/version.c @@ -797,6 +797,10 @@ static char *(features[]) = 5024, /**/ 4214, +/**/ + 4152, +/**/ + 4151, /**/ 4120, /**/