Publicus/cvefixes-security-ir-graphrag huggingface dataset:
CVE-2022-2598: Out-of-bounds Write (CWE-787)
value: Out-of-bounds Write to API in GitHub repository vim/vim prior to 9.0.0100.


CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 5.5
Published: 2022-08-01T15:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/diff.c, src/testdir/test_diffmode.vim, src/version.c
Commit date: 2022-07-28 18:44:27 +0100
Commit message: patch 9.0.0101: invalid memory access in diff mode with "dp" and undo

Problem:    Invalid memory access in diff mode with "dp" and undo.
Solution:   Make sure the line number does not go below one.

Diff: diff --git a/src/diff.c b/src/diff.c
index e4bafe2c934e..fb43eee844cd 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -462,11 +462,14 @@ diff_mark_adjust_tp(
 		    }
 
 		    for (i = 0; i < DB_COUNT; ++i)
 			if (tp->tp_diffbuf[i] != NULL && i != idx)
 			{
-			    dp->df_lnum[i] -= off;
+			    if (dp->df_lnum[i] > off)
+				dp->df_lnum[i] -= off;
+			    else
+				dp->df_lnum[i] = 1;
 			    dp->df_count[i] += n;
 			}
 		}
 		else
 		{
@@ -2861,12 +2864,12 @@ ex_diffgetput(exarg_T *eap)
 	    added = 0;
 	    for (i = 0; i < count; ++i)
 	    {
 		// remember deleting the last line of the buffer
 		buf_empty = curbuf->b_ml.ml_line_count == 1;
-		ml_delete(lnum);
-		--added;
+		if (ml_delete(lnum) == OK)
+		    --added;
 	    }
 	    for (i = 0; i < dp->df_count[idx_from] - start_skip - end_skip; ++i)
 	    {
 		linenr_T nr;
 
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index dcacd5516bb7..41f7fe3493ca 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -1626,7 +1626,21 @@ func Test_diff_manipulations()
 
   set nodiff
   %bwipe!
 endfunc
 
+" This was causing the line number in the diff block to go below one.
+" FIXME: somehow this causes a valgrind error when run directly but not when
+" run as a test.
+func Test_diff_put_and_undo()
+  set diff
+  next 0
+  split 00
+  sil! norm o0gguudpo0ggJuudp
+
+  bwipe!
+  bwipe!
+  set nodiff
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 9e682a5fd635..1241e98b08b0 100644
--- a/src/version.c
+++ b/src/version.c
@@ -733,10 +733,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    101,
 /**/
     100,
 /**/
     99,
 /**/

Vulnerable code: 			    dp->df_lnum[i] -= off;
		ml_delete(lnum);
		--added;
Fixed code: 			    if (dp->df_lnum[i] > off)
				dp->df_lnum[i] -= off;
			    else
				dp->df_lnum[i] = 1;
		if (ml_delete(lnum) == OK)
		    --added;
" This was causing the line number in the diff block to go below one.
" FIXME: somehow this causes a valgrind error when run directly but not when
" run as a test.
func Test_diff_put_and_undo()
  set diff
  next 0
  split 00
  sil! norm o0gguudpo0ggJuudp

  bwipe!
  bwipe!
  set nodiff
endfunc

/**/
    101,
CVE-2022-2816: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read in GitHub repository vim/vim prior to 9.0.0212.
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-08-15T22:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_vim9_cmd.vim, src/version.c, src/vim9cmds.c
Commit date: 2022-08-14 21:46:07 +0100
Commit message: patch 9.0.0212: invalid memory access when compiling :unlet

Problem:    Invalid memory access when compiling :unlet.
Solution:   Don't read past the end of the line.

Diff: diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index 79f19f0389a0..5484ecb7757e 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -1738,16 +1738,23 @@ def Test_lockvar()
   END
   v9.CheckScriptFailure(lines, 'E46', 1)
 
   lines =<< trim END
       def _()
-        s:0([], s:0)
         lockv
       enddef
       defcomp
   END
-  v9.CheckScriptFailure(lines, 'E179', 2)
+  v9.CheckScriptFailure(lines, 'E179', 1)
+
+  lines =<< trim END
+      def T()
+        unlet
+      enddef
+      defcomp
+  END
+  v9.CheckScriptFailure(lines, 'E179', 1)
 enddef
 
 def Test_substitute_expr()
   var to = 'repl'
   new
diff --git a/src/version.c b/src/version.c
index 3f0bf5151ad2..7de71581568e 100644
--- a/src/version.c
+++ b/src/version.c
@@ -733,10 +733,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    212,
 /**/
     211,
 /**/
     210,
 /**/
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index 35a382138bf3..93032d6bf154 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -90,10 +90,16 @@ free_locals(cctx_T *cctx)
  * Check if "name" can be "unlet".
  */
     int
 check_vim9_unlet(char_u *name)
 {
+    if (*name == NUL)
+    {
+	semsg(_(e_argument_required_for_str), "unlet");
+	return FAIL;
+    }
+
     if (name[1] != ':' || vim_strchr((char_u *)"gwtb", *name) == NULL)
     {
 	// "unlet s:var" is allowed in legacy script.
 	if (*name == 's' && !script_is_vim9())
 	    return OK;

Vulnerable code:         s:0([], s:0)
  v9.CheckScriptFailure(lines, 'E179', 2)
Fixed code:   v9.CheckScriptFailure(lines, 'E179', 1)

  lines =<< trim END
      def T()
        unlet
      enddef
      defcomp
  END
  v9.CheckScriptFailure(lines, 'E179', 1)
/**/
    212,
    if (*name == NUL)
    {
	semsg(_(e_argument_required_for_str), "unlet");
	return FAIL;
    }
CVE-2022-2819: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 9.0.0211.
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-08-15T11:21Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_vim9_cmd.vim, src/version.c, src/vim9cmds.c
Commit date: 2022-08-14 21:28:32 +0100
Commit message: patch 9.0.0211: invalid memory access when compiling :lockvar

Problem:    Invalid memory access when compiling :lockvar.
Solution:   Don't read past the end of the line.

Diff: diff --git a/src/testdir/test_vim9_cmd.vim b/src/testdir/test_vim9_cmd.vim
index fc1354e83da3..79f19f0389a0 100644
--- a/src/testdir/test_vim9_cmd.vim
+++ b/src/testdir/test_vim9_cmd.vim
@@ -1735,10 +1735,19 @@ def Test_lockvar()
         unlockvar name
       enddef
       UnLockIt()
   END
   v9.CheckScriptFailure(lines, 'E46', 1)
+
+  lines =<< trim END
+      def _()
+        s:0([], s:0)
+        lockv
+      enddef
+      defcomp
+  END
+  v9.CheckScriptFailure(lines, 'E179', 2)
 enddef
 
 def Test_substitute_expr()
   var to = 'repl'
   new
diff --git a/src/version.c b/src/version.c
index c58386b563ce..3f0bf5151ad2 100644
--- a/src/version.c
+++ b/src/version.c
@@ -733,10 +733,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    211,
 /**/
     210,
 /**/
     209,
 /**/
diff --git a/src/vim9cmds.c b/src/vim9cmds.c
index ad32c32ff7cb..35a382138bf3 100644
--- a/src/vim9cmds.c
+++ b/src/vim9cmds.c
@@ -186,14 +186,21 @@ compile_lock_unlock(
     char_u	*p = lvp->ll_name;
     int		ret = OK;
     size_t	len;
     char_u	*buf;
     isntype_T	isn = ISN_EXEC;
+    char	*cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar";
 
     if (cctx->ctx_skip == SKIP_YES)
 	return OK;
 
+    if (*p == NUL)
+    {
+	semsg(_(e_argument_required_for_str), cmd);
+	return FAIL;
+    }
+
     // Cannot use :lockvar and :unlockvar on local variables.
     if (p[1] != ':')
     {
 	char_u *end = find_name_end(p, NULL, NULL, FNE_CHECK_START);
 
@@ -221,12 +228,10 @@ compile_lock_unlock(
     buf = alloc(len);
     if (buf == NULL)
 	ret = FAIL;
     else
     {
-	char *cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar";
-
 	if (deep < 0)
 	    vim_snprintf((char *)buf, len, "%s! %s", cmd, p);
 	else
 	    vim_snprintf((char *)buf, len, "%s %d %s", cmd, deep, p);
 	ret = generate_EXEC_copy(cctx, isn, buf);

Vulnerable code: 	char *cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar";

Fixed code: 
  lines =<< trim END
      def _()
        s:0([], s:0)
        lockv
      enddef
      defcomp
  END
  v9.CheckScriptFailure(lines, 'E179', 2)
/**/
    211,
    char	*cmd = eap->cmdidx == CMD_lockvar ? "lockvar" : "unlockvar";
    if (*p == NUL)
    {
	semsg(_(e_argument_required_for_str), cmd);
	return FAIL;
    }
CVE-2022-2845: Improper Validation of Specified Quantity in Input (CWE-1284)
value: Improper Validation of Specified Quantity in Input in GitHub repository vim/vim prior to 9.0.0218.


CWE description: The product receives input that is expected to specify a quantity (such as size or length), but it does not validate or incorrectly validates that the quantity has the required properties.
CVSS v3 base score: 7.8
Published: 2022-08-17T15:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/edit.c, src/proto/edit.pro, src/testdir/test_cmdwin.vim, src/version.c
Commit date: 2022-08-16 14:51:53 +0100
Commit message: patch 9.0.0218: reading before the start of the line

Problem:    Reading before the start of the line.
Solution:   When displaying "$" check the column is not negative.

Diff: diff --git a/src/edit.c b/src/edit.c
index 0b0d174f36c3..0b7896476a6e 100644
--- a/src/edit.c
+++ b/src/edit.c
@@ -1744,12 +1744,13 @@ edit_unputchar(void)
 /*
  * Called when p_dollar is set: display a '$' at the end of the changed text
  * Only works when cursor is in the line that changes.
  */
     void
-display_dollar(colnr_T col)
+display_dollar(colnr_T col_arg)
 {
+    colnr_T col = col_arg < 0 ? 0 : col_arg;
     colnr_T save_col;
 
     if (!redrawing())
 	return;
 
diff --git a/src/proto/edit.pro b/src/proto/edit.pro
index a233e401a25b..f35ec1ed5298 100644
--- a/src/proto/edit.pro
+++ b/src/proto/edit.pro
@@ -3,11 +3,11 @@ int edit(int cmdchar, int startln, long count);
 int ins_need_undo_get(void);
 void ins_redraw(int ready);
 void edit_putchar(int c, int highlight);
 void set_insstart(linenr_T lnum, int col);
 void edit_unputchar(void);
-void display_dollar(colnr_T col);
+void display_dollar(colnr_T col_arg);
 void undisplay_dollar(void);
 void truncate_spaces(char_u *line);
 void backspace_until_column(int col);
 int get_literal(int noReduceKeys);
 void insertchar(int c, int flags, int second_indent);
diff --git a/src/testdir/test_cmdwin.vim b/src/testdir/test_cmdwin.vim
index d641b292305c..8cfb248f7480 100644
--- a/src/testdir/test_cmdwin.vim
+++ b/src/testdir/test_cmdwin.vim
@@ -363,7 +363,15 @@ func Test_cant_open_cmdwin_in_cmdwin()
     let caught = v:exception
   endtry
   call assert_match('E1292:', caught)
 endfunc
 
+func Test_cmdwin_virtual_edit()
+  enew!
+  set ve=all cpo+=$
+  silent normal q/s
+
+  set ve= cpo-=$
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 5c7e3a93a04a..5d9f9f77d0af 100644
--- a/src/version.c
+++ b/src/version.c
@@ -733,10 +733,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    218,
 /**/
     217,
 /**/
     216,
 /**/

Vulnerable code: display_dollar(colnr_T col)
void display_dollar(colnr_T col);
Fixed code: display_dollar(colnr_T col_arg)
    colnr_T col = col_arg < 0 ? 0 : col_arg;
void display_dollar(colnr_T col_arg);
func Test_cmdwin_virtual_edit()
  enew!
  set ve=all cpo+=$
  silent normal q/s

  set ve= cpo-=$
endfunc

/**/
    218,
CVE-2022-2923: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository vim/vim prior to 9.0.0240.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2022-08-22T21:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/spellfile.c, src/testdir/test_spellfile.vim, src/version.c
Commit date: 2022-08-21 20:33:47 +0100
Commit message: patch 9.0.0240: crash when using ":mkspell" with an empty .dic file

Problem:    Crash when using ":mkspell" with an empty .dic file.
Solution:   Check for an empty word tree.

Diff: diff --git a/src/spellfile.c b/src/spellfile.c
index 5962a1048f6f..7620affee8e9 100644
--- a/src/spellfile.c
+++ b/src/spellfile.c
@@ -5583,14 +5583,16 @@ sug_filltree(spellinfo_T *spin, slang_T *slang)
     // let tree_add_word() know we're adding to the soundfolded tree
     spin->si_sugtree = TRUE;
 
     /*
      * Go through the whole case-folded tree, soundfold each word and put it
-     * in the trie.
+     * in the trie.  Bail out if the tree is empty.
      */
     byts = slang->sl_fbyts;
     idxs = slang->sl_fidxs;
+    if (byts == NULL || idxs == NULL)
+	return FAIL;
 
     arridx[0] = 0;
     curi[0] = 1;
     wordcount[0] = 0;
 
diff --git a/src/testdir/test_spellfile.vim b/src/testdir/test_spellfile.vim
index 43dfad4628b6..28e69bdc5da6 100644
--- a/src/testdir/test_spellfile.vim
+++ b/src/testdir/test_spellfile.vim
@@ -1166,6 +1166,18 @@ def Test_spellfile_allow_at_character()
   &spellfile = './Xtest/the foo@bar,dir/Xspellfile.add'
   &spellfile = ''
   delete('Xtest', 'rf')
 enddef
 
+" this was using a NULL pointer
+func Test_mkspell_empty_dic()
+  call writefile(['1'], 'XtestEmpty.dic')
+  call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff')
+  mkspell! XtestEmpty.spl XtestEmpty
+
+  call delete('XtestEmpty.dic')
+  call delete('XtestEmpty.aff')
+  call delete('XtestEmpty.spl')
+endfunc
+
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index fe100c81026c..9e77abceea2c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -729,10 +729,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    240,
 /**/
     239,
 /**/
     238,
 /**/

Vulnerable code:      * in the trie.
Fixed code:      * in the trie.  Bail out if the tree is empty.
    if (byts == NULL || idxs == NULL)
	return FAIL;
" this was using a NULL pointer
func Test_mkspell_empty_dic()
  call writefile(['1'], 'XtestEmpty.dic')
  call writefile(['SOFOFROM abcd', 'SOFOTO ABCD', 'SAL CIA X'], 'XtestEmpty.aff')
  mkspell! XtestEmpty.spl XtestEmpty

  call delete('XtestEmpty.dic')
  call delete('XtestEmpty.aff')
  call delete('XtestEmpty.spl')
endfunc


/**/
    240,
CVE-2022-3278: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository vim/vim prior to 9.0.0552.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2022-09-23T22:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/eval.c, src/testdir/test_source.vim, src/version.c
Commit date: 2022-09-22 21:35:19 +0100
Commit message: patch 9.0.0552: crash when using NUL in buffer that uses :source

Problem:    Crash when using NUL in buffer that uses :source.
Solution:   Don't get a next line when skipping over NL.

Diff: diff --git a/src/eval.c b/src/eval.c
index 1f439701ed6c..77f0d7fb3cbd 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -251,11 +251,11 @@ eval_expr_typval(typval_T *expr, typval_T *argv, int argc, typval_T *rettv)
 	    int		r;
 
 	    if (fc == NULL)
 		return FAIL;
 
-	    // Shortcut to call a compiled function without overhead.
+	    // Shortcut to call a compiled function with minimal overhead.
 	    r = call_def_function(partial->pt_func, argc, argv,
 					  DEF_USE_PT_ARGV, partial, fc, rettv);
 	    remove_funccal();
 	    if (r == FAIL)
 		return FAIL;
@@ -2289,11 +2289,11 @@ eval_next_non_blank(char_u *arg, evalarg_T *evalarg, int *getnext)
 	else
 	    next = peek_next_line_from_context(evalarg->eval_cctx);
 
 	if (next != NULL)
 	{
-	    *getnext = TRUE;
+	    *getnext = *p != NL;
 	    return skipwhite(next);
 	}
     }
     return p;
 }
diff --git a/src/testdir/test_source.vim b/src/testdir/test_source.vim
index 44cd2fdc72db..2becf0817e3f 100644
--- a/src/testdir/test_source.vim
+++ b/src/testdir/test_source.vim
@@ -663,7 +663,24 @@ func Test_source_buffer_long_line()
   source Xtest.vim
   bwipe!
   call delete('Xtest.vim')
 endfunc
 
+func Test_source_buffer_with_NUL_char()
+  " This was trying to use a line below the buffer.
+  let lines =<< trim END
+      if !exists('g:loaded')
+        let g:loaded = 1
+        source
+      endif
+  END
+  " Can't have a NL in heredoc
+  let lines += ["silent! vim9 echo [0 \<NL> ? 'a' : 'b']"]
+  call writefile(lines, 'XsourceNul', '')
+  edit XsourceNul
+  source
+
+  bwipe!
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index c3b6c12903a5..505185da500d 100644
--- a/src/version.c
+++ b/src/version.c
@@ -697,10 +697,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    552,
 /**/
     551,
 /**/
     550,
 /**/

Vulnerable code: 	    // Shortcut to call a compiled function without overhead.
	    *getnext = TRUE;
Fixed code: 	    // Shortcut to call a compiled function with minimal overhead.
	    *getnext = *p != NL;
func Test_source_buffer_with_NUL_char()
  " This was trying to use a line below the buffer.
  let lines =<< trim END
      if !exists('g:loaded')
        let g:loaded = 1
        source
      endif
  END
  " Can't have a NL in heredoc
  let lines += ["silent! vim9 echo [0 \<NL> ? 'a' : 'b']"]
  call writefile(lines, 'XsourceNul', '')
  edit XsourceNul
  source

  bwipe!
endfunc

/**/
    552,
CVE-2022-3520: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 9.0.0765.
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: 9.8
Published: 2022-12-02T19:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/register.c, src/testdir/test_visual.vim, src/version.c
Commit date: 2022-10-15 19:04:05 +0100
Commit message: patch 9.0.0765: with a Visual block a put command column may go negative

Problem:    With a Visual block a put command column may go negative.
Solution:   Check that the column does not become negative.

Diff: diff --git a/src/register.c b/src/register.c
index bede88b9a06..21ed43699d4 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1958,10 +1958,12 @@ do_put(
 	curbuf->b_op_start.lnum = lnum;
 
 	// adjust '] mark
 	curbuf->b_op_end.lnum = curwin->w_cursor.lnum - 1;
 	curbuf->b_op_end.col = bd.textcol + totlen - 1;
+	if (curbuf->b_op_end.col < 0)
+	    curbuf->b_op_end.col = 0;
 	curbuf->b_op_end.coladd = 0;
 	if (flags & PUT_CURSEND)
 	{
 	    colnr_T len;
 
diff --git a/src/testdir/test_visual.vim b/src/testdir/test_visual.vim
index 66a44c52ca7..a7f8ec4d41a 100644
--- a/src/testdir/test_visual.vim
+++ b/src/testdir/test_visual.vim
@@ -481,10 +481,22 @@ func Test_visual_block_put()
   call feedkeys("jl\<C-V>ljp", 'xt')
   call assert_equal(['One', 'T', 'Tee', 'One', ''], getline(1, '$'))
   bw!
 endfunc
 
+func Test_visual_block_put_invalid()
+  enew!
+  behave mswin
+  norm yy
+  norm v)Ps/^/	
+  " this was causing the column to become negative
+  silent norm ggv)P
+
+  bwipe!
+  behave xterm
+endfunc
+
 " Visual modes (v V CTRL-V) followed by an operator; count; repeating
 func Test_visual_mode_op()
   new
   call append(0, '')
 
diff --git a/src/version.c b/src/version.c
index dc5e4017779..017b311fbdc 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    765,
 /**/
     764,
 /**/
     763,
 /**/

Fixed code: 	if (curbuf->b_op_end.col < 0)
	    curbuf->b_op_end.col = 0;
func Test_visual_block_put_invalid()
  enew!
  behave mswin
  norm yy
  norm v)Ps/^/	
  " this was causing the column to become negative
  silent norm ggv)P

  bwipe!
  behave xterm
endfunc

/**/
    765,
CVE-2022-47024: NULL Pointer Dereference (CWE-476)
value: A null pointer dereference issue was discovered in function gui_x11_create_blank_mouse in gui_x11.c in vim 8.1.2269 thru 9.0.0339 allows attackers to cause denial of service or other unspecified impacts.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 7.8
Published: 2023-01-20T19:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/gui_x11.c, src/version.c
Commit date: 2022-08-31 12:01:54 +0100
Commit message: patch 9.0.0339: no check if the return value of XChangeGC() is NULL

Problem:    No check if the return value of XChangeGC() is NULL.
Solution:   Only use the return value when it is not NULL. (closes #11020)

Diff: diff --git a/src/gui_x11.c b/src/gui_x11.c
index 6e3e903be46..7293ac4900a 100644
--- a/src/gui_x11.c
+++ b/src/gui_x11.c
@@ -2229,14 +2229,18 @@ gui_mch_set_sp_color(guicolor_T color)
     static Cursor
 gui_x11_create_blank_mouse(void)
 {
     Pixmap blank_pixmap = XCreatePixmap(gui.dpy, gui.wid, 1, 1, 1);
     GC gc = XCreateGC(gui.dpy, blank_pixmap, (unsigned long)0, (XGCValues*)0);
-    XDrawPoint(gui.dpy, blank_pixmap, gc, 0, 0);
-    XFreeGC(gui.dpy, gc);
+
+    if (gc != NULL)
+    {
+	XDrawPoint(gui.dpy, blank_pixmap, gc, 0, 0);
+	XFreeGC(gui.dpy, gc);
+    }
     return XCreatePixmapCursor(gui.dpy, blank_pixmap, blank_pixmap,
-	    (XColor*)&gui.norm_pixel, (XColor*)&gui.norm_pixel, 0, 0);
+		     (XColor*)&gui.norm_pixel, (XColor*)&gui.norm_pixel, 0, 0);
 }
 
 /*
  * Draw a curled line at the bottom of the character cell.
  */
diff --git a/src/version.c b/src/version.c
index 80914885fe2..354a2e43349 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,10 +705,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    339,
 /**/
     338,
 /**/
     337,
 /**/

Vulnerable code:     XDrawPoint(gui.dpy, blank_pixmap, gc, 0, 0);
    XFreeGC(gui.dpy, gc);
	    (XColor*)&gui.norm_pixel, (XColor*)&gui.norm_pixel, 0, 0);
Fixed code: 
    if (gc != NULL)
    {
	XDrawPoint(gui.dpy, blank_pixmap, gc, 0, 0);
	XFreeGC(gui.dpy, gc);
    }
		     (XColor*)&gui.norm_pixel, (XColor*)&gui.norm_pixel, 0, 0);
/**/
    339,
CVE-2023-0049: Out-of-bounds Read (CWE-125)
value: Out-of-bounds Read in GitHub repository vim/vim prior to 9.0.1143.
CWE description: The product reads data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2023-01-04T16:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/buffer.c, src/testdir/test_statusline.vim, src/version.c
Commit date: 2023-01-04 14:31:49 +0000
Commit message: patch 9.0.1143: invalid memory access with bad 'statusline' value

Problem:    Invalid memory access with bad 'statusline' value.
Solution:   Avoid going over the NUL at the end.

Diff: diff --git a/src/buffer.c b/src/buffer.c
index 98568987894..40168226160 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -4615,10 +4615,12 @@ build_stl_str_hl(
 	    continue;
 	}
 #endif
 	if (vim_strchr(STL_ALL, *s) == NULL)
 	{
+	    if (*s == NUL)  // can happen with "%0"
+		break;
 	    s++;
 	    continue;
 	}
 	opt = *s++;
 
diff --git a/src/testdir/test_statusline.vim b/src/testdir/test_statusline.vim
index a829597655b..23613bfed37 100644
--- a/src/testdir/test_statusline.vim
+++ b/src/testdir/test_statusline.vim
@@ -438,10 +438,17 @@ func Test_statusline()
   call delete('Xstatusline')
   set statusline&
   set splitbelow&
 endfunc
 
+func Test_statusline_trailing_percent_zero()
+  " this was causing illegal memory access
+  set laststatus=2 stl=%!%0
+  call assert_fails('redraw', 'E15: Invalid expression: "%0"')
+  set laststatus& stl&
+endfunc
+
 func Test_statusline_visual()
   func CallWordcount()
     call wordcount()
   endfunc
   new x1
diff --git a/src/version.c b/src/version.c
index df02bb87b87..4ccbd537abe 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1143,
 /**/
     1142,
 /**/
     1141,
 /**/

Fixed code: 	    if (*s == NUL)  // can happen with "%0"
		break;
func Test_statusline_trailing_percent_zero()
  " this was causing illegal memory access
  set laststatus=2 stl=%!%0
  call assert_fails('redraw', 'E15: Invalid expression: "%0"')
  set laststatus& stl&
endfunc

/**/
    1143,
CVE-2023-0054: Out-of-bounds Write (CWE-787)
value: Out-of-bounds Write in GitHub repository vim/vim prior to 9.0.1145.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2023-01-04T19:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/eval.c, src/testdir/test_substitute.vim, src/version.c
Commit date: 2023-01-04 17:17:54 +0000
Commit message: patch 9.0.1145: invalid memory access with recursive substitute expression

Problem:    Invalid memory access with recursive substitute expression.
Solution:   Check the return value of vim_regsub().

Diff: diff --git a/src/eval.c b/src/eval.c
index 2fbd867abab..9ca805061d9 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -7310,10 +7310,15 @@ do_string_sub(
 	     * - The text up to where the match is.
 	     * - The substituted text.
 	     * - The text after the match.
 	     */
 	    sublen = vim_regsub(&regmatch, sub, expr, tail, 0, REGSUB_MAGIC);
+	    if (sublen <= 0)
+	    {
+		ga_clear(&ga);
+		break;
+	    }
 	    if (ga_grow(&ga, (int)((end - tail) + sublen -
 			    (regmatch.endp[0] - regmatch.startp[0]))) == FAIL)
 	    {
 		ga_clear(&ga);
 		break;
diff --git a/src/testdir/test_substitute.vim b/src/testdir/test_substitute.vim
index 25132233720..4268aab03fe 100644
--- a/src/testdir/test_substitute.vim
+++ b/src/testdir/test_substitute.vim
@@ -1113,10 +1113,26 @@ func Test_sub_expr_goto_other_file()
 
   delfunc g:SplitGotoFile
   bwipe!
 endfunc
 
+func Test_recursive_expr_substitute()
+  " this was reading invalid memory
+  let lines =<< trim END
+      func Repl(g, n)
+        s
+        r%:s000
+      endfunc
+      next 0
+      let caught = 0
+      s/\%')/\=Repl(0, 0)
+      qall!
+  END
+  call writefile(lines, 'XexprSubst', 'D')
+  call RunVim([], [], '--clean -S XexprSubst')
+endfunc
+
 " Test for the 2-letter and 3-letter :substitute commands
 func Test_substitute_short_cmd()
   new
   call setline(1, ['one', 'one one one'])
   s/one/two
diff --git a/src/version.c b/src/version.c
index 6e652c697cf..9c38fd91cf1 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1145,
 /**/
     1144,
 /**/
     1143,
 /**/

Fixed code: 	    if (sublen <= 0)
	    {
		ga_clear(&ga);
		break;
	    }
func Test_recursive_expr_substitute()
  " this was reading invalid memory
  let lines =<< trim END
      func Repl(g, n)
        s
        r%:s000
      endfunc
      next 0
      let caught = 0
      s/\%')/\=Repl(0, 0)
      qall!
  END
  call writefile(lines, 'XexprSubst', 'D')
  call RunVim([], [], '--clean -S XexprSubst')
endfunc

/**/
    1145,
CVE-2023-0288: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 9.0.1189.
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: 2023-01-13T16:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/normal.c, src/testdir/test_fold.vim, src/version.c
Commit date: 2023-01-13 14:17:58 +0000
Commit message: patch 9.0.1189: invalid memory access with folding and using "L"

Problem:    Invalid memory access with folding and using "L".
Solution:   Prevent the cursor from moving to line zero.

Diff: diff --git a/src/normal.c b/src/normal.c
index c319be599ad..3d9f74dec55 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -3727,11 +3727,12 @@ nv_scroll(cmdarg_T *cap)
 		for (n = cap->count1 - 1; n > 0
 			    && curwin->w_cursor.lnum > curwin->w_topline; --n)
 		{
 		    (void)hasFolding(curwin->w_cursor.lnum,
 						&curwin->w_cursor.lnum, NULL);
-		    --curwin->w_cursor.lnum;
+		    if (curwin->w_cursor.lnum > curwin->w_topline)
+			--curwin->w_cursor.lnum;
 		}
 	    }
 	    else
 #endif
 		curwin->w_cursor.lnum -= cap->count1 - 1;
diff --git a/src/testdir/test_fold.vim b/src/testdir/test_fold.vim
index adf9e520783..f915a661336 100644
--- a/src/testdir/test_fold.vim
+++ b/src/testdir/test_fold.vim
@@ -1673,6 +1673,14 @@ func Test_sort_closed_fold()
         \ ], getline(1, 10))
 
   bwipe!
 endfunc
 
+func Test_indent_with_L_command()
+  " The "L" command moved the cursor to line zero, causing the text saved for
+  " undo to use line number -1, which caused trouble for undo later.
+  new
+  sil! norm 8RV{zf8=Lu
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 1d81e7b6fd3..64f7d887bed 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1189,
 /**/
     1188,
 /**/
     1187,
 /**/

Vulnerable code: 		    --curwin->w_cursor.lnum;
Fixed code: 		    if (curwin->w_cursor.lnum > curwin->w_topline)
			--curwin->w_cursor.lnum;
func Test_indent_with_L_command()
  " The "L" command moved the cursor to line zero, causing the text saved for
  " undo to use line number -1, which caused trouble for undo later.
  new
  sil! norm 8RV{zf8=Lu
  bwipe!
endfunc

/**/
    1189,
CVE-2023-0433: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 9.0.1225.
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: 2023-01-21T15:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/textformat.c, src/version.c
Commit date: 2023-01-21 13:09:19 +0000
Commit message: patch 9.0.1225: reading past the end of a line when formatting text

Problem:    Reading past the end of a line when formatting text.
Solution:   Check for not going over the end of the line.

Diff: diff --git a/src/textformat.c b/src/textformat.c
index 6a93890bd2c..7ebbc8849a4 100644
--- a/src/textformat.c
+++ b/src/textformat.c
@@ -538,10 +538,13 @@ same_leader(
     char_u  *line2;
 
     if (leader1_len == 0)
 	return (leader2_len == 0);
 
+    char_u  *lnum_line = NULL;
+    int	    line_len = 0;
+
     // If first leader has 'f' flag, the lines can be joined only if the
     // second line does not have a leader.
     // If first leader has 'e' flag, the lines can never be joined.
     // If first leader has 's' flag, the lines can only be joined if there is
     // some text after it and the second line has the 'm' flag.
@@ -553,11 +556,16 @@ same_leader(
 		return (leader2_len == 0);
 	    if (*p == COM_END)
 		return FALSE;
 	    if (*p == COM_START)
 	    {
-		if (*(ml_get(lnum) + leader1_len) == NUL)
+		if (lnum_line == NULL)
+		{
+		    lnum_line = ml_get(lnum);
+		    line_len = (int)STRLEN(lnum_line);
+		}
+		if (line_len <= leader1_len)
 		    return FALSE;
 		if (leader2_flags == NULL || leader2_len == 0)
 		    return FALSE;
 		for (p = leader2_flags; *p && *p != ':'; ++p)
 		    if (*p == COM_MIDDLE)
diff --git a/src/version.c b/src/version.c
index 29c788d2b4b..6a11b7fcb1b 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1225,
 /**/
     1224,
 /**/
     1223,
 /**/

Vulnerable code: 		if (*(ml_get(lnum) + leader1_len) == NUL)
Fixed code:     char_u  *lnum_line = NULL;
    int	    line_len = 0;

		if (lnum_line == NULL)
		{
		    lnum_line = ml_get(lnum);
		    line_len = (int)STRLEN(lnum_line);
		}
		if (line_len <= leader1_len)
/**/
    1225,
CVE-2023-1170: Heap-based Buffer Overflow (CWE-122)
value: Heap-based Buffer Overflow in GitHub repository vim/vim prior to 9.0.1376.
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: 2023-03-03T23:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/register.c, src/testdir/test_put.vim, src/version.c
Commit date: 2023-03-03 21:11:52 +0000
Commit message: patch 9.0.1376: accessing invalid memory with put in Visual block mode

Problem:    Accessing invalid memory with put in Visual block mode.
Solution:   Adjust the cursor column if needed.

Diff: diff --git a/src/register.c b/src/register.c
index 4dc0a68fd7a4..461363be378d 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1926,11 +1926,11 @@ do_put(
 	    {
 		mch_memmove(ptr, y_array[i], (size_t)yanklen);
 		ptr += yanklen;
 
 		// insert block's trailing spaces only if there's text behind
-		if ((j < count - 1 || !shortline) && spaces)
+		if ((j < count - 1 || !shortline) && spaces > 0)
 		{
 		    vim_memset(ptr, ' ', (size_t)spaces);
 		    ptr += spaces;
 		}
 		else
@@ -2282,10 +2282,19 @@ error:
     }
 
     msgmore(nr_lines);
     curwin->w_set_curswant = TRUE;
 
+    // Make sure the cursor is not after the NUL.
+    int len = (int)STRLEN(ml_get_curline());
+    if (curwin->w_cursor.col > len)
+    {
+	if (cur_ve_flags == VE_ALL)
+	    curwin->w_cursor.coladd = curwin->w_cursor.col - len;
+	curwin->w_cursor.col = len;
+    }
+
 end:
     if (cmdmod.cmod_flags & CMOD_LOCKMARKS)
     {
 	curbuf->b_op_start = orig_start;
 	curbuf->b_op_end = orig_end;
diff --git a/src/testdir/test_put.vim b/src/testdir/test_put.vim
index 66438bd3f69c..a6cea74efb6c 100644
--- a/src/testdir/test_put.vim
+++ b/src/testdir/test_put.vim
@@ -229,7 +229,18 @@ func Test_put_visual_mode()
 
   bwipe!
   set selection&
 endfunc
 
+func Test_put_visual_block_mode()
+  enew
+  exe "norm 0R\<CR>\<C-C>V"
+  sil exe "norm \<C-V>c	\<MiddleDrag>"
+  set ve=all
+  sil norm vz=p
+
+  bwipe!
+  set ve=
+endfunc
+
 
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 8f26bdf47a26..022b9ffe8777 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1376,
 /**/
     1375,
 /**/
     1374,
 /**/

Vulnerable code: 		if ((j < count - 1 || !shortline) && spaces)
Fixed code: 		if ((j < count - 1 || !shortline) && spaces > 0)
    // Make sure the cursor is not after the NUL.
    int len = (int)STRLEN(ml_get_curline());
    if (curwin->w_cursor.col > len)
    {
	if (cur_ve_flags == VE_ALL)
	    curwin->w_cursor.coladd = curwin->w_cursor.col - len;
	curwin->w_cursor.col = len;
    }

func Test_put_visual_block_mode()
  enew
  exe "norm 0R\<CR>\<C-C>V"
  sil exe "norm \<C-V>c	\<MiddleDrag>"
  set ve=all
  sil norm vz=p

  bwipe!
  set ve=
endfunc

/**/
    1376,
CVE-2023-1175: Incorrect Calculation of Buffer Size (CWE-131)
value: Incorrect Calculation of Buffer Size in GitHub repository vim/vim prior to 9.0.1378.
CWE description: The product does not correctly calculate the size to be used when allocating a buffer, which could lead to a buffer overflow.
CVSS v3 base score: 6.6
Published: 2023-03-04T16:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/register.c, src/testdir/test_virtualedit.vim, src/version.c
Commit date: 2023-03-04 14:13:10 +0000
Commit message: patch 9.0.1378: illegal memory access when using virtual editing

Problem:    Illegal memory access when using virtual editing.
Solution:   Make sure "startspaces" is not negative.

Diff: diff --git a/src/register.c b/src/register.c
index 461363be378d..f3df79cfd642 100644
--- a/src/register.c
+++ b/src/register.c
@@ -1243,10 +1243,12 @@ op_yank(oparg_T *oap, int deleting, int mess)
 			    {
 				// Part of a tab selected -- but don't
 				// double-count it.
 				bd.startspaces = (ce - cs + 1)
 							  - oap->start.coladd;
+				if (bd.startspaces < 0)
+				    bd.startspaces = 0;
 				startcol++;
 			    }
 			}
 		    }
 
diff --git a/src/testdir/test_virtualedit.vim b/src/testdir/test_virtualedit.vim
index 71cea427bac1..edaae678609d 100644
--- a/src/testdir/test_virtualedit.vim
+++ b/src/testdir/test_virtualedit.vim
@@ -86,10 +86,20 @@ func Test_edit_change()
   call assert_equal(['a  x', 'b  x', 'c  x'], getline(1, '$'))
   bwipe!
   set virtualedit=
 endfunc
 
+func Test_edit_special_char()
+  new
+  se ve=all
+  norm a0
+  sil! exe "norm o00000\<Nul>k<a0s"
+
+  bwipe!
+  set virtualedit=
+endfunc
+
 " Tests for pasting at the beginning, end and middle of a tab character
 " in virtual edit mode.
 func Test_paste_in_tab()
   new
   call append(0, '')
diff --git a/src/version.c b/src/version.c
index a9cf30e2f080..c93499c416b4 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1378,
 /**/
     1377,
 /**/
     1376,
 /**/

Fixed code: 				if (bd.startspaces < 0)
				    bd.startspaces = 0;
func Test_edit_special_char()
  new
  se ve=all
  norm a0
  sil! exe "norm o00000\<Nul>k<a0s"

  bwipe!
  set virtualedit=
endfunc

/**/
    1378,
CVE-2023-1355: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository vim/vim prior to 9.0.1402.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2023-03-11T22:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/testdir/test_vim9_class.vim, src/version.c, src/vim9class.c
Commit date: 2023-03-11 20:56:35 +0000
Commit message: patch 9.0.1402: crash when using null_class

Problem:    Crash when using null_class.
Solution:   Give an error when trying to use a null class.

Diff: diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index bc8a8e1d548a..4b6a730bbd77 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -201,10 +201,17 @@ def Test_returning_null_object()
       echo buffers.Current()
   END
   v9.CheckScriptSuccess(lines)
 enddef
 
+def Test_using_null_class()
+  var lines =<< trim END
+      @_ = null_class.member
+  END
+  v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
+enddef
+
 def Test_class_interface_wrong_end()
   var lines =<< trim END
       vim9script
       abstract class SomeName
         this.member = 'text'
diff --git a/src/version.c b/src/version.c
index 0265c47a90f6..2dca10db9d50 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1402,
 /**/
     1401,
 /**/
     1400,
 /**/
diff --git a/src/vim9class.c b/src/vim9class.c
index 74664f1b2691..8174351383bc 100644
--- a/src/vim9class.c
+++ b/src/vim9class.c
@@ -1260,10 +1260,16 @@ class_object_index(
 	    return FAIL;
 	}
 	cl = rettv->vval.v_object->obj_class;
     }
 
+    if (cl == NULL)
+    {
+	emsg(_(e_incomplete_type));
+	return FAIL;
+    }
+
     if (*name_end == '(')
     {
 	int on_class = rettv->v_type == VAR_CLASS;
 	int count = on_class ? cl->class_class_function_count
 			     : cl->class_obj_method_count;

Fixed code: def Test_using_null_class()
  var lines =<< trim END
      @_ = null_class.member
  END
  v9.CheckDefExecAndScriptFailure(lines, ['E715:', 'E1363:'])
enddef

/**/
    1402,
    if (cl == NULL)
    {
	emsg(_(e_incomplete_type));
	return FAIL;
    }
CVE-2023-2609: NULL Pointer Dereference (CWE-476)
value: NULL Pointer Dereference in GitHub repository vim/vim prior to 9.0.1531.
CWE description: The product dereferences a pointer that it expects to be valid but is NULL.
CVSS v3 base score: 5.5
Published: 2023-05-09T18:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/register.c, src/testdir/test_registers.vim, src/version.c
Commit date: 2023-05-09 17:09:30 +0100
Commit message: patch 9.0.1531: crash when register contents ends up being invalid

Problem:    Crash when register contents ends up being invalid.
Solution:   Check "y_array" is not NULL.

Diff: diff --git a/src/register.c b/src/register.c
index f3df79cfd642..e481d843c249 100644
--- a/src/register.c
+++ b/src/register.c
@@ -299,11 +299,11 @@ get_register(
 
     *reg = *y_current;
     if (copy)
     {
 	// If we run out of memory some or all of the lines are empty.
-	if (reg->y_size == 0)
+	if (reg->y_size == 0 || y_current->y_array == NULL)
 	    reg->y_array = NULL;
 	else
 	    reg->y_array = ALLOC_MULT(char_u *, reg->y_size);
 	if (reg->y_array != NULL)
 	{
diff --git a/src/testdir/test_registers.vim b/src/testdir/test_registers.vim
index e966932478d8..33ea0f4bd3e6 100644
--- a/src/testdir/test_registers.vim
+++ b/src/testdir/test_registers.vim
@@ -833,10 +833,27 @@ func Test_end_reg_executing()
 
   nunmap s
   bwipe!
 endfunc
 
+" This was causing a crash because y_append was ending up being NULL
+func Test_zero_y_append()
+  " Run in a separate Vim instance because changing 'encoding' may cause
+  " trouble for later tests.
+  let lines =<< trim END
+      d
+      silent ?n
+      next <sfile>
+      so
+      sil! norm 0VPSP
+      set enc=latin1
+       
+  END
+  call writefile(lines, 'XTest_zero_y_append', 'D')
+  call RunVim([], [], '-u NONE -i NONE -e -s -S XTest_zero_y_append -c qa\!')
+endfunc
+
 " Make sure that y_append is correctly reset
 " and the previous register is working as expected
 func Test_register_y_append_reset()
   new
   call setline(1, ['1',
diff --git a/src/version.c b/src/version.c
index 310803cb8293..7ee9f575f9bd 100644
--- a/src/version.c
+++ b/src/version.c
@@ -693,10 +693,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1531,
 /**/
     1530,
 /**/
     1529,
 /**/

Vulnerable code: 	if (reg->y_size == 0)
Fixed code: 	if (reg->y_size == 0 || y_current->y_array == NULL)
" This was causing a crash because y_append was ending up being NULL
func Test_zero_y_append()
  " Run in a separate Vim instance because changing 'encoding' may cause
  " trouble for later tests.
  let lines =<< trim END
      d
      silent ?n
      next <sfile>
      so
      sil! norm 0VPSP
      set enc=latin1
       
  END
  call writefile(lines, 'XTest_zero_y_append', 'D')
  call RunVim([], [], '-u NONE -i NONE -e -s -S XTest_zero_y_append -c qa\!')
endfunc

/**/
    1531,
CVE-2023-4734: Integer Overflow or Wraparound (CWE-190)
value: Integer Overflow or Wraparound in GitHub repository vim/vim prior to 9.0.1846.
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: 7.8
Published: 2023-09-02T18:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/ex_docmd.c, src/testdir/test_functions.vim, src/version.c
Commit date: 2023-09-02 19:30:03 +0200
Commit message: patch 9.0.1846: [security] crash in fullcommand

Problem:  crash in fullcommand
Solution: Check for typeval correctly

Signed-off-by: Christian Brabandt <cb@256bit.org>

Diff: diff --git a/src/ex_docmd.c b/src/ex_docmd.c
index 32d52ab21218..10d979d493ac 100644
--- a/src/ex_docmd.c
+++ b/src/ex_docmd.c
@@ -4085,11 +4085,11 @@ f_fullcommand(typval_T *argvars, typval_T *rettv)
     if (in_vim9script()
 	    && (check_for_string_arg(argvars, 0) == FAIL
 		|| check_for_opt_bool_arg(argvars, 1) == FAIL))
 	return;
 
-    name = argvars[0].vval.v_string;
+    name = tv_get_string(&argvars[0]);
     if (name == NULL)
 	return;
 
     if (argvars[1].v_type != VAR_UNKNOWN)
     {
diff --git a/src/testdir/test_functions.vim b/src/testdir/test_functions.vim
index 0eda5de380e9..ab1dbf3b5985 100644
--- a/src/testdir/test_functions.vim
+++ b/src/testdir/test_functions.vim
@@ -3605,6 +3605,11 @@ func Test_string_reverse()
   set encoding=latin1
   call assert_equal('dcba', reverse('abcd'))
   let &encoding = save_enc
 endfunc
 
+func Test_fullcommand()
+  " this used to crash vim
+  call assert_equal('', fullcommand(10))
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
diff --git a/src/version.c b/src/version.c
index 3de6046ffb02..5cde7c185525 100644
--- a/src/version.c
+++ b/src/version.c
@@ -697,10 +697,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1846,
 /**/
     1845,
 /**/
     1844,
 /**/

Vulnerable code:     name = argvars[0].vval.v_string;
Fixed code:     name = tv_get_string(&argvars[0]);
func Test_fullcommand()
  " this used to crash vim
  call assert_equal('', fullcommand(10))
endfunc

/**/
    1846,
CVE-2023-4735: Out-of-bounds Write (CWE-787)
value: Out-of-bounds Write in GitHub repository vim/vim prior to 9.0.1847.
CWE description: The product writes data past the end, or before the beginning, of the intended buffer.
CVSS v3 base score: 7.8
Published: 2023-09-02T18:15Z
Repository: https://github.com/vim/vim
Language: C
Files changed: src/ops.c, src/version.c
Commit date: 2023-09-02 19:43:33 +0200
Commit message: patch 9.0.1847: [security] potential oob write in do_addsub()

Problem:  potential oob write in do_addsub()
Solution: don't overflow buf2, check size in for loop()

Signed-off-by: Christian Brabandt <cb@256bit.org>

Diff: diff --git a/src/ops.c b/src/ops.c
index d46a049fe4e7..f4524d3d7b12 100644
--- a/src/ops.c
+++ b/src/ops.c
@@ -2917,11 +2917,11 @@ do_addsub(
 
 	    // leading zeros
 	    for (bit = bits; bit > 0; bit--)
 		if ((n >> (bit - 1)) & 0x1) break;
 
-	    for (i = 0; bit > 0; bit--)
+	    for (i = 0; bit > 0 && i < (NUMBUFLEN - 1); bit--)
 		buf2[i++] = ((n >> (bit - 1)) & 0x1) ? '1' : '0';
 
 	    buf2[i] = '\0';
 	}
 	else if (pre == 0)
diff --git a/src/version.c b/src/version.c
index 5cde7c185525..c638a107e30f 100644
--- a/src/version.c
+++ b/src/version.c
@@ -697,10 +697,12 @@ static char *(features[]) =
 	NULL
 };
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1847,
 /**/
     1846,
 /**/
     1845,
 /**/

Vulnerable code: 	    for (i = 0; bit > 0; bit--)
Fixed code: 	    for (i = 0; bit > 0 && i < (NUMBUFLEN - 1); bit--)
/**/
    1847,