diff -up vim82/src/charset.c.cve4193 vim82/src/charset.c --- vim82/src/charset.c.cve4193 2021-03-22 10:02:42.000000000 +0100 +++ vim82/src/charset.c 2022-01-13 10:14:55.634913386 +0100 @@ -1232,10 +1232,15 @@ getvcol( posptr = NULL; // continue until the NUL else { - // Special check for an empty line, which can happen on exit, when - // ml_get_buf() always returns an empty string. - if (*ptr == NUL) - pos->col = 0; + colnr_T i; + + // In a few cases the position can be beyond the end of the line. + for (i = 0; i < pos->col; ++i) + if (ptr[i] == NUL) + { + pos->col = i; + break; + } posptr = ptr + pos->col; if (has_mbyte) // always start on the first byte diff -up vim82/src/testdir/test_regexp_latin.vim.cve4193 vim82/src/testdir/test_regexp_latin.vim --- vim82/src/testdir/test_regexp_latin.vim.cve4193 2022-01-13 10:14:55.634913386 +0100 +++ vim82/src/testdir/test_regexp_latin.vim 2022-01-13 10:17:01.905292715 +0100 @@ -938,4 +938,12 @@ func Test_regexp_last_subst_string() close! endfunc +func Test_using_invalid_visual_position() + " this was going beyond the end of the line + new + exe "norm 0o000\0\$s0" + /\%V + bwipe! +endfunc + " vim: shiftwidth=2 sts=2 expandtab