Publicus/cvefixes-security-ir-graphrag huggingface dataset:
CVE-2015-5219: Incorrect Type Conversion or Cast (CWE-704)
value: The ULOGTOD function in ntp.d in SNTP before 4.2.7p366 does not properly perform type conversions from a precision value to a double, which allows remote attackers to cause a denial of service (infinite loop) via a crafted NTP packet.
CWE description: The product does not correctly convert an object, resource, or structure from one type to a different type.
CVSS v3 base score: 7.5
Published: 2017-07-21T14:29Z
Repository: https://github.com/ntp-project/ntp
Language: Other
Files changed: ChangeLog, include/ntp.h
Commit date: 2013-04-24 19:13:53 -0400
Commit message: [Bug 2382] Implement LOGTOD using ldexp() instead of shifting

Diff: diff --git a/ChangeLog b/ChangeLog
index f8a3dd6f4..56c7b18e7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,7 @@
 * [Bug 1485] Sometimes ntpd crashes
+* [Bug 2382] Implement LOGTOD using ldexp() instead of shifting.
 (4.2.7p366) 2013/04/17 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 1866] Disable some debugging output in refclock_oncore.
 (4.2.7p365) 2013/04/16 Released by Harlan Stenn <stenn@ntp.org>
 * [Bug 2149] Log an error message if /proc/net/if_inet6 cannot be opened.
 (4.2.7p364) 2013/03/26 Released by Harlan Stenn <stenn@ntp.org>
diff --git a/include/ntp.h b/include/ntp.h
index aa45e1604..95b2542ab 100644
--- a/include/ntp.h
+++ b/include/ntp.h
@@ -154,14 +154,13 @@ typedef char s_char;
  * amplitude. Whether this makes statistical sense may be arguable.
  */
 #define SQUARE(x) ((x) * (x))
 #define SQRT(x) (sqrt(x))
 #define DIFF(x, y) (SQUARE((x) - (y)))
-#define LOGTOD(a)	((a) < 0 ? 1. / (1L << -(a)) : \
-			    1L << (int)(a)) /* log2 to double */
+#define LOGTOD(a)	ldexp(1., (int)(a)) /* log2 to double */
 #define UNIVAR(x)	(SQUARE(.28867513 * LOGTOD(x))) /* std uniform distr */
-#define ULOGTOD(a)	(1L << (int)(a)) /* ulog2 to double */
+#define ULOGTOD(a)	ldexp(1., (int)(a)) /* ulog2 to double */
 
 #define	EVENT_TIMEOUT	0	/* one second, that is */
 
 
 /*

Vulnerable code: #define LOGTOD(a)	((a) < 0 ? 1. / (1L << -(a)) : \
			    1L << (int)(a)) /* log2 to double */
#define ULOGTOD(a)	(1L << (int)(a)) /* ulog2 to double */
Fixed code: * [Bug 2382] Implement LOGTOD using ldexp() instead of shifting.
#define LOGTOD(a)	ldexp(1., (int)(a)) /* log2 to double */
#define ULOGTOD(a)	ldexp(1., (int)(a)) /* ulog2 to double */
CVE-2017-5953: Integer Overflow or Wraparound (CWE-190)
value: vim before patch 8.0.0322 does not properly validate values for tree length when handling a spell file, which may result in an integer overflow at a memory allocation site and a resultant buffer overflow.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 9.8
Published: 2017-02-10T07:59Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/spellfile.c, src/version.c
Commit date: 2017-02-09 21:07:12 +0100
Commit message: patch 8.0.0322: possible overflow with corrupted spell file

Problem:    Possible overflow with spell file where the tree length is
            corrupted.
Solution:   Check for an invalid length (suggested by shqking)

Diff: diff --git a/src/spellfile.c b/src/spellfile.c
index c7d87c6c7..8b1a3a633 100644
--- a/src/spellfile.c
+++ b/src/spellfile.c
@@ -1593,10 +1593,13 @@ spell_read_tree(
     /* The tree size was computed when writing the file, so that we can
      * allocate it as one long block. <nodecount> */
     len = get4c(fd);
     if (len < 0)
 	return SP_TRUNCERROR;
+    if (len >= 0x3ffffff)
+	/* Invalid length, multiply with sizeof(int) would overflow. */
+	return SP_FORMERROR;
     if (len > 0)
     {
 	/* Allocate the byte array. */
 	bp = lalloc((long_u)len, TRUE);
 	if (bp == NULL)
diff --git a/src/version.c b/src/version.c
index 7a3d21513..c1a5186ba 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,10 +762,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    322,
 /**/
     321,
 /**/
     320,
 /**/

Fixed code:     if (len >= 0x3ffffff)
	/* Invalid length, multiply with sizeof(int) would overflow. */
	return SP_FORMERROR;
/**/
    322,
CVE-2017-6349: Integer Overflow or Wraparound (CWE-190)
value: An integer overflow at a u_read_undo memory allocation site would occur for vim before patch 8.0.0377, if it does not properly validate values for tree length when reading a corrupted undo file, which may lead to resultant buffer overflows.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 9.8
Published: 2017-02-27T07:59Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/undo.c, src/version.c
Commit date: 2017-02-26 18:11:36 +0100
Commit message: patch 8.0.0377: possible overflow when reading corrupted undo file

Problem:    Possible overflow when reading corrupted undo file.
Solution:   Check if allocated size is not too big. (King)

Diff: diff --git a/src/undo.c b/src/undo.c
index b69f31872..ba7c0b83c 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1785,11 +1785,11 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
     long	version, str_len;
     char_u	*line_ptr = NULL;
     linenr_T	line_lnum;
     colnr_T	line_colnr;
     linenr_T	line_count;
-    int		num_head = 0;
+    long	num_head = 0;
     long	old_header_seq, new_header_seq, cur_header_seq;
     long	seq_last, seq_cur;
     long	last_save_nr = 0;
     short	old_idx = -1, new_idx = -1, cur_idx = -1;
     long	num_read_uhps = 0;
@@ -1972,11 +1972,12 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
      * until we insert them into curbuf. The table remains sorted by the
      * sequence numbers of the headers.
      * When there are no headers uhp_table is NULL. */
     if (num_head > 0)
     {
-	uhp_table = (u_header_T **)U_ALLOC_LINE(
+	if (num_head < LONG_MAX / (long)sizeof(u_header_T *))
+	    uhp_table = (u_header_T **)U_ALLOC_LINE(
 					     num_head * sizeof(u_header_T *));
 	if (uhp_table == NULL)
 	    goto error;
     }
 
diff --git a/src/version.c b/src/version.c
index 8d1454197..c79020b21 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,10 +762,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    377,
 /**/
     376,
 /**/
     375,
 /**/

Vulnerable code:     int		num_head = 0;
	uhp_table = (u_header_T **)U_ALLOC_LINE(
Fixed code:     long	num_head = 0;
	if (num_head < LONG_MAX / (long)sizeof(u_header_T *))
	    uhp_table = (u_header_T **)U_ALLOC_LINE(
/**/
    377,
CVE-2017-6350: Integer Overflow or Wraparound (CWE-190)
value: An integer overflow at an unserialize_uep memory allocation site would occur for vim before patch 8.0.0378, if it does not properly validate values for tree length when reading a corrupted undo file, which may lead to resultant buffer overflows.
CWE description: The product performs a calculation that can
         produce an integer overflow or wraparound when the logic
         assumes that the resulting value will always be larger than
         the original value. This occurs when an integer value is
         incremented to a value that is too large to store in the
         associated representation. When this occurs, the value may
         become a very small or negative number.
CVSS v3 base score: 9.8
Published: 2017-02-27T07:59Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/undo.c, src/version.c
Commit date: 2017-02-26 18:17:10 +0100
Commit message: patch 8.0.0378: possible overflow when reading corrupted undo file

Problem:    Another possible overflow when reading corrupted undo file.
Solution:   Check if allocated size is not too big. (King)

Diff: diff --git a/src/undo.c b/src/undo.c
index ba7c0b83c..5b953795e 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1383,11 +1383,11 @@ serialize_uep(
     static u_entry_T *
 unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
 {
     int		i;
     u_entry_T	*uep;
-    char_u	**array;
+    char_u	**array = NULL;
     char_u	*line;
     int		line_len;
 
     uep = (u_entry_T *)U_ALLOC_LINE(sizeof(u_entry_T));
     if (uep == NULL)
@@ -1400,20 +1400,19 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
     uep->ue_bot = undo_read_4c(bi);
     uep->ue_lcount = undo_read_4c(bi);
     uep->ue_size = undo_read_4c(bi);
     if (uep->ue_size > 0)
     {
-	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
+	if (uep->ue_size < LONG_MAX / (int)sizeof(char_u *))
+	    array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
 	if (array == NULL)
 	{
 	    *error = TRUE;
 	    return uep;
 	}
 	vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
     }
-    else
-	array = NULL;
     uep->ue_array = array;
 
     for (i = 0; i < uep->ue_size; ++i)
     {
 	line_len = undo_read_4c(bi);
diff --git a/src/version.c b/src/version.c
index c79020b21..026b82981 100644
--- a/src/version.c
+++ b/src/version.c
@@ -762,10 +762,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    378,
 /**/
     377,
 /**/
     376,
 /**/

Vulnerable code:     char_u	**array;
	array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
    else
	array = NULL;
Fixed code:     char_u	**array = NULL;
	if (uep->ue_size < LONG_MAX / (int)sizeof(char_u *))
	    array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
/**/
    378,
CVE-2019-12735: Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection') (CWE-78)
value: getchar.c in Vim before 8.1.1365 and Neovim before 0.3.6 allows remote attackers to execute arbitrary OS commands via the :source! command in a modeline, as demonstrated by execute in Vim, and assert_fails or nvim_input in Neovim.
CWE description: The product constructs all or part of an OS command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended OS command when it is sent to a downstream component.
CVSS v3 base score: 8.6
Published: 2019-06-05T14:29Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/getchar.c, src/testdir/test_source.vim, src/version.c
Commit date: 2019-05-22 22:38:25 +0200
Commit message: patch 8.1.1365: source command doesn't check for the sandbox

Problem:    Source command doesn't check for the sandbox. (Armin Razmjou)
Solution:   Check for the sandbox when sourcing a file.

Diff: diff --git a/src/getchar.c b/src/getchar.c
index 9379a6a8d4..debad7efd2 100644
--- a/src/getchar.c
+++ b/src/getchar.c
@@ -1405,10 +1405,16 @@ openscript(
     if (curscript + 1 == NSCRIPT)
     {
 	emsg(_(e_nesting));
 	return;
     }
+
+    // Disallow sourcing a file in the sandbox, the commands would be executed
+    // later, possibly outside of the sandbox.
+    if (check_secure())
+	return;
+
 #ifdef FEAT_EVAL
     if (ignore_script)
 	/* Not reading from script, also don't open one.  Warning message? */
 	return;
 #endif
diff --git a/src/testdir/test_source.vim b/src/testdir/test_source.vim
index a33d286e75..5166bafb15 100644
--- a/src/testdir/test_source.vim
+++ b/src/testdir/test_source.vim
@@ -34,5 +34,14 @@ func Test_source_cmd()
 
   au! SourceCmd
   au! SourcePre
   au! SourcePost
 endfunc
+
+func Test_source_sandbox()
+  new
+  call writefile(["Ohello\<Esc>"], 'Xsourcehello')
+  source! Xsourcehello | echo
+  call assert_equal('hello', getline(1))
+  call assert_fails('sandbox source! Xsourcehello', 'E48:')
+  bwipe!
+endfunc
diff --git a/src/version.c b/src/version.c
index b0736df46a..b2fcbfb14c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -765,10 +765,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1365,
 /**/
     1364,
 /**/
     1363,
 /**/

Fixed code: 
    // Disallow sourcing a file in the sandbox, the commands would be executed
    // later, possibly outside of the sandbox.
    if (check_secure())
	return;


func Test_source_sandbox()
  new
  call writefile(["Ohello\<Esc>"], 'Xsourcehello')
  source! Xsourcehello | echo
  call assert_equal('hello', getline(1))
  call assert_fails('sandbox source! Xsourcehello', 'E48:')
  bwipe!
endfunc
/**/
    1365,
CVE-2019-20079: Use After Free (CWE-416)
value: The autocmd feature in window.c in Vim before 8.1.2136 accesses freed memory.
CWE description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
CVSS v3 base score: 7.8
Published: 2019-12-30T01:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_autocmd.vim, src/version.c, src/window.c
Commit date: 2019-10-11 21:19:13 +0200
Commit message: patch 8.1.2136: using freed memory with autocmd from fuzzer

Problem:    using freed memory with autocmd from fuzzer. (Dhiraj Mishra,
            Dominique Pelle)
Solution:   Avoid using "wp" after autocommands. (closes #5041)

Diff: diff --git a/src/testdir/test_autocmd.vim b/src/testdir/test_autocmd.vim
index fe77bf5786..1e53fe4639 100644
--- a/src/testdir/test_autocmd.vim
+++ b/src/testdir/test_autocmd.vim
@@ -2286,5 +2286,13 @@ func Test_autocmd_CmdWinEnter()
 
   " clean up
   call StopVimInTerminal(buf)
   call delete(filename)
 endfunc
+
+func Test_autocmd_was_using_freed_memory()
+  pedit xx
+  n x
+  au WinEnter * quit
+  split
+  au! WinEnter
+endfunc
diff --git a/src/version.c b/src/version.c
index f22db55478..46bd1b19c6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -751,10 +751,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2136,
 /**/
     2135,
 /**/
     2134,
 /**/
diff --git a/src/window.c b/src/window.c
index 0fda9f05c6..fb8a5a7ede 100644
--- a/src/window.c
+++ b/src/window.c
@@ -4639,10 +4639,11 @@ win_enter_ext(
     }
 
 #ifdef FEAT_JOB_CHANNEL
     entering_window(curwin);
 #endif
+    // Careful: autocommands may close the window and make "wp" invalid
     if (trigger_new_autocmds)
 	apply_autocmds(EVENT_WINNEW, NULL, NULL, FALSE, curbuf);
     if (trigger_enter_autocmds)
     {
 	apply_autocmds(EVENT_WINENTER, NULL, NULL, FALSE, curbuf);
@@ -4653,11 +4654,11 @@ win_enter_ext(
 #ifdef FEAT_TITLE
     maketitle();
 #endif
     curwin->w_redr_status = TRUE;
 #ifdef FEAT_TERMINAL
-    if (bt_terminal(wp->w_buffer))
+    if (bt_terminal(curwin->w_buffer))
 	// terminal is likely in another mode
 	redraw_mode = TRUE;
 #endif
     redraw_tabline = TRUE;
     if (restart_edit)

Vulnerable code:     if (bt_terminal(wp->w_buffer))
Fixed code: 
func Test_autocmd_was_using_freed_memory()
  pedit xx
  n x
  au WinEnter * quit
  split
  au! WinEnter
endfunc
/**/
    2136,
    // Careful: autocommands may close the window and make "wp" invalid
    if (bt_terminal(curwin->w_buffer))
CVE-2021-3875: Heap-based Buffer Overflow (CWE-122)
value: vim is vulnerable to Heap-based Buffer Overflow
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 5.5
Published: 2021-10-15T14:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/ex_docmd.c, src/testdir/test_search.vim, src/version.c
Commit date: 2021-10-09 13:58:55 +0100
Commit message: patch 8.2.3489: ml_get error after search with range

Problem:    ml_get error after search with range.
Solution:   Limit the line number to the buffer line count.

Diff: diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 2c55e67bc3..08a48305ed 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4227,12 +4227,14 @@ get_address(
 
 		    pos = curwin->w_cursor; // save curwin->w_cursor
 
 		    // When '/' or '?' follows another address, start from
 		    // there.
-		    if (lnum != MAXLNUM)
-			curwin->w_cursor.lnum = lnum;
+		    if (lnum > 0 && lnum != MAXLNUM)
+			curwin->w_cursor.lnum =
+				lnum > curbuf->b_ml.ml_line_count
+					   ? curbuf->b_ml.ml_line_count : lnum;
 
 		    // Start a forward search at the end of the line (unless
 		    // before the first line).
 		    // Start a backward search at the start of the line.
 		    // This makes sure we never match in the current
diff --git a/src/testdir/test_search.vim b/src/testdir/test_search.vim
index bb4e45defa..eaf9c23269 100644
--- a/src/testdir/test_search.vim
+++ b/src/testdir/test_search.vim
@@ -1987,7 +1987,21 @@ func Test_no_last_search_pattern()
   call feedkeys("//\<C-T>", 'xt')
   call feedkeys("??\<C-G>", 'xt')
   call feedkeys("??\<C-T>", 'xt')
 endfunc
 
+func Test_search_with_invalid_range()
+  new
+  let lines =<< trim END
+    /\%.v
+    5/
+    c
+  END
+  call writefile(lines, 'Xrangesearch')
+  source Xrangesearch
+
+  bwipe!
+  call delete('Xrangesearch')
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index f3fbd45bc2..43f87aabec 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,10 +755,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3489,
 /**/
     3488,
 /**/
     3487,
 /**/

Vulnerable code: 		    if (lnum != MAXLNUM)
			curwin->w_cursor.lnum = lnum;
Fixed code: 		    if (lnum > 0 && lnum != MAXLNUM)
			curwin->w_cursor.lnum =
				lnum > curbuf->b_ml.ml_line_count
					   ? curbuf->b_ml.ml_line_count : lnum;
func Test_search_with_invalid_range()
  new
  let lines =<< trim END
    /\%.v
    5/
    c
  END
  call writefile(lines, 'Xrangesearch')
  source Xrangesearch

  bwipe!
  call delete('Xrangesearch')
endfunc

/**/
    3489,
CVE-2021-3984: Heap-based Buffer Overflow (CWE-122)
value: vim is vulnerable to Heap-based Buffer Overflow
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 7.8
Published: 2021-12-01T11:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/cindent.c, src/testdir/test_cindent.vim, src/version.c
Commit date: 2021-11-19 19:41:13 +0000
Commit message: patch 8.2.3625: illegal memory access when C-indenting

Problem:    Illegal memory access when C-indenting.
Solution:   Also set the cursor column.

Diff: diff --git a/src/cindent.c b/src/cindent.c
index 850a3699473..ad3052249dc 100644
--- a/src/cindent.c
+++ b/src/cindent.c
@@ -1635,14 +1635,14 @@ get_baseclass_amount(int col)
 // }
 
     static pos_T *
 find_start_brace(void)	    // XXX
 {
-    pos_T	cursor_save;
-    pos_T	*trypos;
-    pos_T	*pos;
-    static pos_T	pos_copy;
+    pos_T	    cursor_save;
+    pos_T	    *trypos;
+    pos_T	    *pos;
+    static pos_T    pos_copy;
 
     cursor_save = curwin->w_cursor;
     while ((trypos = findmatchlimit(NULL, '{', FM_BLOCKSTOP, 0)) != NULL)
     {
 	pos_copy = *trypos;	// copy pos_T, next findmatch will change it
@@ -1652,11 +1652,11 @@ find_start_brace(void)	    // XXX
 	// ignore the { if it's in a // or / *  * / comment
 	if ((colnr_T)cin_skip2pos(trypos) == trypos->col
 		       && (pos = ind_find_start_CORS(NULL)) == NULL) // XXX
 	    break;
 	if (pos != NULL)
-	    curwin->w_cursor.lnum = pos->lnum;
+	    curwin->w_cursor = *pos;
     }
     curwin->w_cursor = cursor_save;
     return trypos;
 }
 
diff --git a/src/testdir/test_cindent.vim b/src/testdir/test_cindent.vim
index 3a536c4c89a..c097ca766d4 100644
--- a/src/testdir/test_cindent.vim
+++ b/src/testdir/test_cindent.vim
@@ -5312,6 +5312,18 @@ func Test_backslash_at_end_of_line()
   exe "norm v>O'\\\<C-m>-"
   exe "norm \<C-q>="
   bwipe!
 endfunc
 
+func Test_find_brace_backwards()
+  " this was looking beyond the end of the line
+  new
+  norm R/*
+  norm o0{
+  norm o//
+  norm V{=
+  call assert_equal(['/*', '   0{', '//'], getline(1, 3))
+  bwipe!
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 7cadcebf04d..8e84cbb4569 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,10 +755,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3625,
 /**/
     3624,
 /**/
     3623,
 /**/

Vulnerable code:     pos_T	cursor_save;
    pos_T	*trypos;
    pos_T	*pos;
    static pos_T	pos_copy;
	    curwin->w_cursor.lnum = pos->lnum;
Fixed code:     pos_T	    cursor_save;
    pos_T	    *trypos;
    pos_T	    *pos;
    static pos_T    pos_copy;
	    curwin->w_cursor = *pos;
func Test_find_brace_backwards()
  " this was looking beyond the end of the line
  new
  norm R/*
  norm o0{
  norm o//
  norm V{=
  call assert_equal(['/*', '   0{', '//'], getline(1, 3))
  bwipe!
endfunc


/**/
    3625,
CVE-2021-4019: Heap-based Buffer Overflow (CWE-122)
value: vim is vulnerable to Heap-based Buffer Overflow
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 7.8
Published: 2021-12-01T10:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/help.c, src/testdir/test_help.vim, src/version.c
Commit date: 2021-11-25 10:50:12 +0000
Commit message: patch 8.2.3669: buffer overflow with long help argument

Problem:    Buffer overflow with long help argument.
Solution:   Use snprintf().

Diff: diff --git a/src/help.c b/src/help.c
index 28d914c8233..d67f78b08ec 100644
--- a/src/help.c
+++ b/src/help.c
@@ -420,12 +420,11 @@ find_help_tags(
 	if (arg[0] == '\\'
 		&& ((arg[1] != NUL && arg[2] == NUL)
 		    || (vim_strchr((char_u *)"%_z@", arg[1]) != NULL
 							   && arg[2] != NUL)))
 	{
-	    STRCPY(d, "/\\\\");
-	    STRCPY(d + 3, arg + 1);
+	    vim_snprintf((char *)d, IOSIZE, "/\\\\%s", arg + 1);
 	    // Check for "/\\_$", should be "/\\_\$"
 	    if (d[3] == '_' && d[4] == '$')
 		STRCPY(d + 4, "\\$");
 	}
 	else
diff --git a/src/testdir/test_help.vim b/src/testdir/test_help.vim
index 15cc642d173..6e32edd368e 100644
--- a/src/testdir/test_help.vim
+++ b/src/testdir/test_help.vim
@@ -132,6 +132,15 @@ func Test_help_window_height()
   call assert_equal(14, winheight(0))
   set helpheight& cmdheight=1
   close
 endfunc
 
+func Test_help_long_argument()
+  try
+    exe 'help \%' .. repeat('0', 1021)
+  catch
+    call assert_match("E149:", v:exception)
+  endtry
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index a225e182f2c..da5871e32f8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -755,10 +755,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3669,
 /**/
     3668,
 /**/
     3667,
 /**/

Vulnerable code: 	    STRCPY(d, "/\\\\");
	    STRCPY(d + 3, arg + 1);
Fixed code: 	    vim_snprintf((char *)d, IOSIZE, "/\\\\%s", arg + 1);
func Test_help_long_argument()
  try
    exe 'help \%' .. repeat('0', 1021)
  catch
    call assert_match("E149:", v:exception)
  endtry
endfunc


/**/
    3669,
CVE-2021-4166: Out-of-bounds Read (CWE-125)
value: vim is vulnerable to Out-of-bounds Read
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.1
Published: 2021-12-25T19:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/arglist.c, src/testdir/test_arglist.vim, src/version.c
Commit date: 2021-12-24 18:11:27 +0000
Commit message: patch 8.2.3884: crash when clearing the argument list while using it

Problem:    Crash when clearing the argument list while using it.
Solution:   Lock the argument list for ":all".

Diff: diff --git a/src/arglist.c b/src/arglist.c
index 24b0a870e21..af8ce740fcd 100644
--- a/src/arglist.c
+++ b/src/arglist.c
@@ -908,10 +908,11 @@ do_arg_all(
     int		had_tab = cmdmod.cmod_tab;
     win_T	*old_curwin, *last_curwin;
     tabpage_T	*old_curtab, *last_curtab;
     win_T	*new_curwin = NULL;
     tabpage_T	*new_curtab = NULL;
+    int		prev_arglist_locked = arglist_locked;
 
 #ifdef FEAT_CMDWIN
     if (cmdwin_type != 0)
     {
 	emsg(_(e_invalid_in_cmdline_window));
@@ -934,10 +935,11 @@ do_arg_all(
     // Autocommands may do anything to the argument list.  Make sure it's not
     // freed while we are working here by "locking" it.  We still have to
     // watch out for its size to be changed.
     alist = curwin->w_alist;
     ++alist->al_refcount;
+    arglist_locked = TRUE;
 
     old_curwin = curwin;
     old_curtab = curtab;
 
 # ifdef FEAT_GUI
@@ -1153,10 +1155,11 @@ do_arg_all(
 	    cmdmod.cmod_tab = 9999;
     }
 
     // Remove the "lock" on the argument list.
     alist_unlink(alist);
+    arglist_locked = prev_arglist_locked;
 
     --autocmd_no_enter;
 
     // restore last referenced tabpage's curwin
     if (last_curtab != new_curtab)
diff --git a/src/testdir/test_arglist.vim b/src/testdir/test_arglist.vim
index b1f292975a9..d29a228e6cb 100644
--- a/src/testdir/test_arglist.vim
+++ b/src/testdir/test_arglist.vim
@@ -581,6 +581,13 @@ func Test_all_not_allowed_from_cmdwin()
   endtry
   call assert_equal('yes', caught)
   au! BufEnter
 endfunc
 
+func Test_clear_arglist_in_all()
+  n 0 00 000 0000 00000 000000
+  au! * 0 n 0
+  all
+  au! *
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 05b8120a98c..7277d2f092e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,10 +747,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3884,
 /**/
     3883,
 /**/
     3882,
 /**/

Fixed code:     int		prev_arglist_locked = arglist_locked;
    arglist_locked = TRUE;
    arglist_locked = prev_arglist_locked;
func Test_clear_arglist_in_all()
  n 0 00 000 0000 00000 000000
  au! * 0 n 0
  all
  au! *
endfunc

/**/
    3884,
CVE-2021-4193: Out-of-bounds Read (CWE-125)
value: vim is vulnerable to Out-of-bounds Read
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2021-12-31T16:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/charset.c, src/testdir/test_regexp_latin.vim, src/version.c
Commit date: 2021-12-30 15:29:18 +0000
Commit message: patch 8.2.3950: going beyond the end of the line with /\%V

Problem:    Going beyond the end of the line with /\%V.
Solution:   Check for valid column in getvcol().

Diff: diff --git a/src/charset.c b/src/charset.c
index 31b03eb38a1..d762a2545bf 100644
--- a/src/charset.c
+++ b/src/charset.c
@@ -1238,14 +1238,19 @@ getvcol(
     line = ptr = ml_get_buf(wp->w_buffer, pos->lnum, FALSE);
     if (pos->col == MAXCOL)
 	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
 	    posptr -= (*mb_head_off)(line, posptr);
     }
diff --git a/src/testdir/test_regexp_latin.vim b/src/testdir/test_regexp_latin.vim
index 03efdbea30e..f936549e7aa 100644
--- a/src/testdir/test_regexp_latin.vim
+++ b/src/testdir/test_regexp_latin.vim
@@ -1051,6 +1051,14 @@ func Test_using_visual_position()
   exe "norm 0o\<Esc>\<C-V>k\<C-X>o0"
   /\%V
   bwipe!
 endfunc
 
+func Test_using_invalid_visual_position()
+  " this was going beyond the end of the line
+  new
+  exe "norm 0o000\<Esc>0\<C-V>$s0"
+  /\%V
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 9f5ed308a1f..56d900dc2c0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -747,10 +747,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    3950,
 /**/
     3949,
 /**/
     3948,
 /**/

Vulnerable code: 	// 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;
Fixed code: 	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;
	    }
func Test_using_invalid_visual_position()
  " this was going beyond the end of the line
  new
  exe "norm 0o000\<Esc>0\<C-V>$s0"
  /\%V
  bwipe!
endfunc

/**/
    3950,
CVE-2022-0158: Heap-based Buffer Overflow (CWE-122)
value: vim is vulnerable to Heap-based Buffer Overflow
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 3.3
Published: 2022-01-10T16:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_vim9_expr.vim, src/version.c, src/vim9expr.c
Commit date: 2022-01-09 13:36:28 +0000
Commit message: patch 8.2.4049: Vim9: reading before the start of the line with "$"

Problem:    Vim9: reading before the start of the line with "$" by itself.
Solution:   Do not subtract one when reporting the error.

Diff: diff --git a/src/testdir/test_vim9_expr.vim b/src/testdir/test_vim9_expr.vim
index 01b45385084..52237e33fdf 100644
--- a/src/testdir/test_vim9_expr.vim
+++ b/src/testdir/test_vim9_expr.vim
@@ -2851,10 +2851,11 @@ def Test_expr7_environment()
       assert_equal('', $ASDF_ASD_XXX)
   END
   CheckDefAndScriptSuccess(lines)
 
   CheckDefAndScriptFailure(["var x = $$$"], ['E1002:', 'E15:'], 1)
+  CheckDefAndScriptFailure(["$"], ['E1002:', 'E15:'], 1)
 enddef
 
 def Test_expr7_register()
   var lines =<< trim END
       @a = 'register a'
diff --git a/src/version.c b/src/version.c
index be49f09e2b5..cf0665c02ce 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4049,
 /**/
     4048,
 /**/
     4047,
 /**/
diff --git a/src/vim9expr.c b/src/vim9expr.c
index 83c68a9ffa2..edaee509976 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -1231,11 +1231,11 @@ compile_get_env(char_u **arg, cctx_T *cctx)
 
     ++*arg;
     len = get_env_len(arg);
     if (len == 0)
     {
-	semsg(_(e_syntax_error_at_str), start - 1);
+	semsg(_(e_syntax_error_at_str), start);
 	return FAIL;
     }
 
     // include the '$' in the name, eval_env_var() expects it.
     name = vim_strnsave(start, len + 1);

Vulnerable code: 	semsg(_(e_syntax_error_at_str), start - 1);
Fixed code:   CheckDefAndScriptFailure(["$"], ['E1002:', 'E15:'], 1)
/**/
    4049,
	semsg(_(e_syntax_error_at_str), start);
CVE-2022-0213: Heap-based Buffer Overflow (CWE-122)
value: vim is vulnerable to Heap-based Buffer Overflow
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 6.6
Published: 2022-01-14T13:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/drawscreen.c, src/testdir/test_edit.vim, src/version.c
Commit date: 2022-01-13 13:08:14 +0000
Commit message: patch 8.2.4074: going over the end of NameBuff

Problem:    Going over the end of NameBuff.
Solution:   Check length when appending a space.

Diff: diff --git a/src/drawscreen.c b/src/drawscreen.c
index 28a2072959f..453ca91c33a 100644
--- a/src/drawscreen.c
+++ b/src/drawscreen.c
@@ -460,16 +460,17 @@ win_redr_status(win_T *wp, int ignore_pum UNUSED)
 
 	get_trans_bufname(wp->w_buffer);
 	p = NameBuff;
 	len = (int)STRLEN(p);
 
-	if (bt_help(wp->w_buffer)
+	if ((bt_help(wp->w_buffer)
 #ifdef FEAT_QUICKFIX
-		|| wp->w_p_pvw
+		    || wp->w_p_pvw
 #endif
-		|| bufIsChanged(wp->w_buffer)
-		|| wp->w_buffer->b_p_ro)
+		    || bufIsChanged(wp->w_buffer)
+		    || wp->w_buffer->b_p_ro)
+		&& len < MAXPATHL - 1)
 	    *(p + len++) = ' ';
 	if (bt_help(wp->w_buffer))
 	{
 	    vim_snprintf((char *)p + len, MAXPATHL - len, "%s", _("[Help]"));
 	    len += (int)STRLEN(p + len);
diff --git a/src/testdir/test_edit.vim b/src/testdir/test_edit.vim
index e83d67250c2..63226466ee9 100644
--- a/src/testdir/test_edit.vim
+++ b/src/testdir/test_edit.vim
@@ -2101,7 +2101,22 @@ func Test_edit_CTRL_hat()
   call assert_equal(0, &iminsert)
 
   bwipe!
 endfunc
 
+" Weird long file name was going over the end of NameBuff
+func Test_edit_overlong_file_name()
+  CheckUnix
+
+  file 0000000000000000000000000000
+  file %%%%%%%%%%%%%%%%%%%%%%%%%%
+  file %%%%%%
+  set readonly
+  set ls=2 
+
+  redraw!
+  set noreadonly ls&
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 1b37a5d50ab..1f4a0316224 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4074,
 /**/
     4073,
 /**/
     4072,
 /**/

Vulnerable code: 	if (bt_help(wp->w_buffer)
		|| wp->w_p_pvw
		|| bufIsChanged(wp->w_buffer)
		|| wp->w_buffer->b_p_ro)
Fixed code: 	if ((bt_help(wp->w_buffer)
		    || wp->w_p_pvw
		    || bufIsChanged(wp->w_buffer)
		    || wp->w_buffer->b_p_ro)
		&& len < MAXPATHL - 1)
" Weird long file name was going over the end of NameBuff
func Test_edit_overlong_file_name()
  CheckUnix

  file 0000000000000000000000000000
  file %%%%%%%%%%%%%%%%%%%%%%%%%%
  file %%%%%%
  set readonly
  set ls=2 

  redraw!
  set noreadonly ls&
  bwipe!
endfunc

/**/
    4074,
CVE-2022-0319: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read in vim/vim prior to 8.2.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2022-01-21T14:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_visual.vim, src/version.c, src/window.c
Commit date: 2022-01-20 13:32:50 +0000
Commit message: patch 8.2.4154: ml_get error when exchanging windows in Visual mode

Problem:    ml_get error when exchanging windows in Visual mode.
Solution:   Correct end of Visual area when entering another buffer.

Diff: diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index a187aa8e085..72f5388b934 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1316,7 +1316,17 @@ func Test_visual_block_insert_round_off()
   call setline(1, ['xxxxx', repeat('0', 1350), "\t", repeat('x', 60)])
   exe "normal gg0\<C-V>GI" .. repeat('0', 1320) .. "\<Esc>"
   bwipe!
 endfunc
 
+" this was causing an ml_get error
+func Test_visual_exchange_windows()
+  enew!
+  new
+  call setline(1, ['foo', 'bar'])
+  exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
+  bwipe!
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 54a9ebee55c..e32abbb79af 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4154,
 /**/
     4153,
 /**/
     4152,
 /**/
diff --git a/src/window.c b/src/window.c
index 05e85baf366..74257275c7c 100644
--- a/src/window.c
+++ b/src/window.c
@@ -1689,10 +1689,15 @@ win_exchange(long Prenum)
     frame_fix_width(curwin);
     frame_fix_width(wp);
 
     (void)win_comp_pos();		// recompute window positions
 
+    if (wp->w_buffer != curbuf)
+	reset_VIsual_and_resel();
+    else if (VIsual_active)
+	wp->w_cursor = curwin->w_cursor;
+
     win_enter(wp, TRUE);
     redraw_all_later(NOT_VALID);
 }
 
 /*
@@ -5330,11 +5335,11 @@ frame_remove(frame_T *frp)
  */
     int
 win_alloc_lines(win_T *wp)
 {
     wp->w_lines_valid = 0;
-    wp->w_lines = ALLOC_CLEAR_MULT(wline_T, Rows );
+    wp->w_lines = ALLOC_CLEAR_MULT(wline_T, Rows);
     if (wp->w_lines == NULL)
 	return FAIL;
     return OK;
 }
 

Vulnerable code:     wp->w_lines = ALLOC_CLEAR_MULT(wline_T, Rows );
Fixed code: " this was causing an ml_get error
func Test_visual_exchange_windows()
  enew!
  new
  call setline(1, ['foo', 'bar'])
  exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
  bwipe!
  bwipe!
endfunc

/**/
    4154,
    if (wp->w_buffer != curbuf)
	reset_VIsual_and_resel();
    else if (VIsual_active)
	wp->w_cursor = curwin->w_cursor;

    wp->w_lines = ALLOC_CLEAR_MULT(wline_T, Rows);
CVE-2022-0361: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 8.2.
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 7.8
Published: 2022-01-26T13:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/ex_cmds.c, src/testdir/test_visual.vim, src/version.c
Commit date: 2022-01-25 13:52:53 +0000
Commit message: patch 8.2.4215: illegal memory access when copying lines in Visual mode

Problem:    Illegal memory access when copying lines in Visual mode.
Solution:   Adjust the Visual position after copying lines.

Diff: diff --git a/src/ex_cmds.c b/src/ex_cmds.c
index 95209985e19..f5d93e66453 100644
--- a/src/ex_cmds.c
+++ b/src/ex_cmds.c
@@ -864,10 +864,12 @@ ex_copy(linenr_T line1, linenr_T line2, linenr_T n)
 	    ++line2;
 	++curwin->w_cursor.lnum;
     }
 
     appended_lines_mark(n, count);
+    if (VIsual_active)
+	check_pos(curbuf, &VIsual);
 
     msgmore((long)count);
 }
 
 static char_u	*prevcmd = NULL;	// the previous command
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 72f5388b934..9b322fd211b 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1326,7 +1326,18 @@ func Test_visual_exchange_windows()
   exe "normal G\<C-V>gg\<C-W>\<C-X>OO\<Esc>"
   bwipe!
   bwipe!
 endfunc
 
+" this was leaving the end of the Visual area beyond the end of a line
+func Test_visual_ex_copy_line()
+  new
+  call setline(1, ["aaa", "bbbbbbbbbxbb"])
+  /x
+  exe "normal ggvjfxO"
+  t0
+  normal gNU
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 5d7eccb1910..ddc34d864be 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4215,
 /**/
     4214,
 /**/
     4213,
 /**/

Fixed code:     if (VIsual_active)
	check_pos(curbuf, &VIsual);
" this was leaving the end of the Visual area beyond the end of a line
func Test_visual_ex_copy_line()
  new
  call setline(1, ["aaa", "bbbbbbbbbxbb"])
  /x
  exe "normal ggvjfxO"
  t0
  normal gNU
  bwipe!
endfunc

/**/
    4215,
CVE-2022-0368: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read in GitHub repository vim/vim prior to 8.2.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2022-01-26T18:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_visual.vim, src/undo.c, src/version.c
Commit date: 2022-01-25 18:24:00 +0000
Commit message: patch 8.2.4217: illegal memory access when undo makes Visual area invalid

Problem:    Illegal memory access when undo makes Visual area invalid.
Solution:   Correct the Visual area after undo.

Diff: diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 9b322fd211b..b2beda08d0a 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -1337,7 +1337,22 @@ func Test_visual_ex_copy_line()
   t0
   normal gNU
   bwipe!
 endfunc
 
+" This was leaving the end of the Visual area beyond the end of a line.
+" Set 'undolevels' to start a new undo block.
+func Test_visual_undo_deletes_last_line()
+  new
+  call setline(1, ["aaa", "ccc", "dyd"])
+  set undolevels=100
+  exe "normal obbbbbbbbbxbb\<Esc>"
+  set undolevels=100
+  /y
+  exe "normal ggvjfxO"
+  undo
+  normal gNU
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/undo.c b/src/undo.c
index 4d186d45325..636144aefd1 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -3027,10 +3027,12 @@ u_undo_end(
 	    if (wp->w_buffer == curbuf && wp->w_p_cole > 0)
 		redraw_win_later(wp, NOT_VALID);
 	}
     }
 #endif
+    if (VIsual_active)
+	check_pos(curbuf, &VIsual);
 
     smsg_attr_keep(0, _("%ld %s; %s #%ld  %s"),
 	    u_oldcount < 0 ? -u_oldcount : u_oldcount,
 	    _(msgstr),
 	    did_undo ? _("before") : _("after"),
diff --git a/src/version.c b/src/version.c
index f5f9a2ef942..6685b554f53 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4217,
 /**/
     4216,
 /**/
     4215,
 /**/

Fixed code: " This was leaving the end of the Visual area beyond the end of a line.
" Set 'undolevels' to start a new undo block.
func Test_visual_undo_deletes_last_line()
  new
  call setline(1, ["aaa", "ccc", "dyd"])
  set undolevels=100
  exe "normal obbbbbbbbbxbb\<Esc>"
  set undolevels=100
  /y
  exe "normal ggvjfxO"
  undo
  normal gNU
  bwipe!
endfunc

    if (VIsual_active)
	check_pos(curbuf, &VIsual);
/**/
    4217,
CVE-2022-0392: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim prior to 8.2.
CWE description: A heap overflow condition is a buffer overflow, where the buffer that can be overwritten is allocated in the heap portion of memory, generally meaning that the buffer was allocated using a routine such as malloc().
CVSS v3 base score: 7.8
Published: 2022-01-28T22:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/edit.c, src/testdir/test_paste.vim, src/version.c
Commit date: 2022-01-25 20:45:16 +0000
Commit message: patch 8.2.4218: illegal memory access with bracketed paste in Ex mode

Problem:    Illegal memory access with bracketed paste in Ex mode.
Solution:   Reserve space for the trailing NUL.

Diff: diff --git a/src/edit.c b/src/edit.c
index ee3caf0dad5..2b5301100dd 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -4450,11 +4450,12 @@ bracketed_paste(paste_mode_T mode, int drop, garray_T *gap)
 		case PASTE_CMDLINE:
 		    put_on_cmdline(buf, idx, TRUE);
 		    break;
 
 		case PASTE_EX:
-		    if (gap != NULL && ga_grow(gap, idx) == OK)
+		    // add one for the NUL that is going to be appended
+		    if (gap != NULL && ga_grow(gap, idx + 1) == OK)
 		    {
 			mch_memmove((char *)gap->ga_data + gap->ga_len,
 							     buf, (size_t)idx);
 			gap->ga_len += idx;
 		    }
diff --git a/src/testdir/test_paste.vim b/src/testdir/test_paste.vim
index c94fe7c357e..5b8d8a0e3e2 100644
--- a/src/testdir/test_paste.vim
+++ b/src/testdir/test_paste.vim
@@ -88,10 +88,13 @@ endfunc
 " bracketed paste in Ex-mode
 func Test_paste_ex_mode()
   unlet! foo
   call feedkeys("Qlet foo=\"\<Esc>[200~foo\<CR>bar\<Esc>[201~\"\<CR>vi\<CR>", 'xt')
   call assert_equal("foo\rbar", foo)
+
+  " pasting more than 40 bytes
+  exe "norm Q\<PasteStart>0000000000000000000000000000000000000000000000000000000000000000000000\<C-C>"
 endfunc
 
 func Test_paste_onechar()
   new
   let @f='abc'
diff --git a/src/version.c b/src/version.c
index 6685b554f53..9dcf34928f8 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4218,
 /**/
     4217,
 /**/
     4216,
 /**/

Vulnerable code: 		    if (gap != NULL && ga_grow(gap, idx) == OK)
Fixed code: 		    // add one for the NUL that is going to be appended
		    if (gap != NULL && ga_grow(gap, idx + 1) == OK)

  " pasting more than 40 bytes
  exe "norm Q\<PasteStart>0000000000000000000000000000000000000000000000000000000000000000000000\<C-C>"
/**/
    4218,
CVE-2022-0572: Out-of-bounds Write (CWE-787)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 8.2.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2022-02-14T12:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/indent.c, src/testdir/test_retab.vim, src/version.c
Commit date: 2022-02-12 15:42:18 +0000
Commit message: patch 8.2.4359: crash when repeatedly using :retab

Problem:    crash when repeatedly using :retab.
Solution:   Bail out when the line is getting too long.

Diff: diff --git a/src/indent.c b/src/indent.c
index 9b137b0b425..232c534973a 100644
--- a/src/indent.c
+++ b/src/indent.c
@@ -1748,10 +1748,15 @@ ex_retab(exarg_T *eap)
 		num_spaces = 0;
 	    }
 	    if (ptr[col] == NUL)
 		break;
 	    vcol += chartabsize(ptr + col, (colnr_T)vcol);
+	    if (vcol >= MAXCOL)
+	    {
+		emsg(_(e_resulting_text_too_long));
+		break;
+	    }
 	    if (has_mbyte)
 		col += (*mb_ptr2len)(ptr + col);
 	    else
 		++col;
 	}
diff --git a/src/testdir/test_retab.vim b/src/testdir/test_retab.vim
index c7190aaa669..6133e8fb4ab 100644
--- a/src/testdir/test_retab.vim
+++ b/src/testdir/test_retab.vim
@@ -68,16 +68,35 @@ func Test_retab()
   call assert_equal("    a       b        c    ",         Retab('!', ''))
   call assert_equal("    a       b        c    ",         Retab('',  3))
   call assert_equal("    a       b        c    ",         Retab('!', 3))
   call assert_equal("    a       b        c    ",         Retab('',  5))
   call assert_equal("    a       b        c    ",         Retab('!', 5))
+
+  set tabstop& expandtab&
 endfunc
 
 func Test_retab_error()
   call assert_fails('retab -1',  'E487:')
   call assert_fails('retab! -1', 'E487:')
   call assert_fails('ret -1000', 'E487:')
   call assert_fails('ret 10000', 'E475:')
   call assert_fails('ret 80000000000000000000', 'E475:')
 endfunc
 
+func Test_retab_endless()
+  new
+  call setline(1, "\t0\t")
+  let caught = 'no'
+  try
+    while 1
+      set ts=4000
+      retab 4
+    endwhile
+  catch /E1240/
+    let caught = 'yes'
+  endtry
+  bwipe!
+  set tabstop&
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 636757c3b6a..aaafadf89de 100644
--- a/src/version.c
+++ b/src/version.c
@@ -748,10 +748,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    4359,
 /**/
     4358,
 /**/
     4357,
 /**/

Fixed code: 	    if (vcol >= MAXCOL)
	    {
		emsg(_(e_resulting_text_too_long));
		break;
	    }

  set tabstop& expandtab&
func Test_retab_endless()
  new
  call setline(1, "\t0\t")
  let caught = 'no'
  try
    while 1
      set ts=4000
      retab 4
    endwhile
  catch /E1240/
    let caught = 'yes'
  endtry
  bwipe!
  set tabstop&
endfunc


/**/
    4359,