hitoshura25/cvefixes huggingface dataset:
CVE-2017-6349 (C, published 2017-02-27T07:59Z)
Description: 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.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
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.
Repository: https://github.com/vim/vim
Files changed:
src/undo.c
src/version.c
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)


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 (C, published 2017-02-27T07:59Z)
Description: 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.
Severity: HIGH (CVSS v3 base score: 9.8)
Weakness: CWE-190 \u2014 Integer Overflow or Wraparound
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.
Repository: https://github.com/vim/vim
Files changed:
src/undo.c
src/version.c
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)


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-2018-20786 (C, published 2019-02-24T14:29Z)
Description: value: libvterm through 0+bzr726, as used in Vim and other products, mishandles certain out-of-memory conditions, leading to a denial of service (application crash), related to screen.c, state.c, and vterm.c.
Severity: MEDIUM (CVSS v3 base score: 7.5)
Weakness: CWE-476 \u2014 NULL Pointer Dereference
The product dereferences a pointer that it expects to be valid but is NULL.
Repository: https://github.com/vim/vim
Files changed:
src/libvterm/src/state.c
src/libvterm/src/termscreen.c
src/libvterm/src/vterm.c
src/terminal.c
src/version.c
Commit message: patch 8.1.0633: crash when out of memory while opening a terminal window

Problem:    Crash when out of memory while opening a terminal window.
Solution:   Handle out-of-memory more gracefully.


Vulnerable code:
  if(buffer)
    vterm_allocator_free(screen->vt, buffer);
  if(screen->sb_buffer)
    vterm_allocator_free(screen->vt, screen->sb_buffer);
  if(!state)



  if(screen->buffers[1])
    vterm_allocator_free(screen->vt, screen->buffers[1]);


  (*vt->allocator->free)(ptr, vt->allocdata);
    static void
	    vterm_obtain_state(vterm),
    state = vterm_obtain_state(vterm);
    create_vterm(term, term->tl_rows, term->tl_cols);
    create_vterm(term, term->tl_rows, term->tl_cols);
    create_vterm(term, term->tl_rows, term->tl_cols);
    create_vterm(term, term->tl_rows, term->tl_cols);

Fixed code:
  if (state == NULL)
    return NULL;
/*
 * Return the existing state or create a new one.
 * Returns NULL when out of memory.
 */
  if (state == NULL)
    return NULL;
/* vim: set sw=2 : */
  vterm_allocator_free(screen->vt, buffer);
  vterm_allocator_free(screen->vt, screen->sb_buffer);
/*
 * Allocate a new screen and return it.
 * Return NULL when out of memory.
 */
  if (state == NULL)
  if (screen == NULL)
    return NULL;
  if (screen->buffer == NULL || screen->sb_buffer == NULL)
  {
    vterm_screen_free(screen);
    return NULL;
  }
  vterm_allocator_free(screen->vt, screen->buffers[1]);
/* vim: set sw=2 : */
  if (vt == NULL)
    return NULL;
  if (vt->parser.strbuffer == NULL)
  {
    vterm_allocator_free(vt, vt);
    return NULL;
  }
  if (vt->outbuffer == NULL)
  {
    vterm_allocator_free(vt, vt->parser.strbuffer);
    vterm_allocator_free(vt, vt);
    return NULL;
  }
/*
 * Free "ptr" unless it is NULL.
 */
  if (ptr)
    (*vt->allocator->free)(ptr, vt->allocdata);

 * Return FAIL when out of memory.
    static int
    if (vterm == NULL)
	return FAIL;

    // Allocate screen and state here, so we can bail out if that fails.
    state = vterm_obtain_state(vterm);
    if (state == NULL || screen == NULL)
    {
	vterm_free(vterm);
	return FAIL;
    }

	    state,

    return OK;
    if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
	goto failed;
    if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
	return FAIL;
    if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
	return FAIL;
    if (create_vterm(term, term->tl_rows, term->tl_cols) == FAIL)
	return FAIL;
/**/
    633,
CVE-2019-12735 (C, published 2019-06-05T14:29Z)
Description: 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.
Severity: HIGH (CVSS v3 base score: 8.6)
Weakness: CWE-78 \u2014 Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection')
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.
Repository: https://github.com/vim/vim
Files changed:
src/getchar.c
src/testdir/test_source.vim
src/version.c
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.


Vulnerable code:

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 (C, published 2019-12-30T01:15Z)
Description: value: The autocmd feature in window.c in Vim before 8.1.2136 accesses freed memory.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/vim/vim
Files changed:
src/testdir/test_autocmd.vim
src/version.c
src/window.c
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)


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-3796 (C, published 2021-09-15T13:15Z)
Description: value: vim is vulnerable to Use After Free
Severity: MEDIUM (CVSS v3 base score: 7.3)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/vim/vim
Files changed:
src/normal.c
src/testdir/test_edit.vim
src/version.c
Commit message: patch 8.2.3428: using freed memory when replacing

Problem:    Using freed memory when replacing. (Dhiraj Mishra)
Solution:   Get the line pointer after calling ins_copychar().


Vulnerable code:
		 * released the line.  At the same time we let know that the
		 * line will be changed.
		ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);

Fixed code:
		 * released the line.  This may also happen in ins_copychar().
		 * At the same time we let know that the line will be changed.

		  ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
		{
		    ptr = ml_get_buf(curbuf, curwin->w_cursor.lnum, TRUE);
		}
" Test for getting the character of the line below after "p"
func Test_edit_put_CTRL_E()
  set encoding=latin1
  new
  let @" = ''
  sil! norm orggRx
  sil! norm pr
  call assert_equal(['r', 'r'], getline(1, 2))
  bwipe!
  set encoding=utf-8
endfunc

/**/
    3428,
CVE-2021-3875 (C, published 2021-10-15T14:15Z)
Description: value: vim is vulnerable to Heap-based Buffer Overflow
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-122 \u2014 Heap-based Buffer Overflow
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().
Repository: https://github.com/vim/vim
Files changed:
src/ex_docmd.c
src/testdir/test_search.vim
src/version.c
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.


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-3903 (C, published 2021-10-27T21:15Z)
Description: value: vim is vulnerable to Heap-based Buffer Overflow
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-122 \u2014 Heap-based Buffer Overflow
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().
Repository: https://github.com/vim/vim
Files changed:
src/move.c
src/testdir/test_normal.vim
src/version.c
Commit message: patch 8.2.3564: invalid memory access when scrolling without valid screen

Problem:    Invalid memory access when scrolling without a valid screen.
Solution:   Do not set VALID_BOTLINE in w_valid.


Vulnerable code:
	curwin->w_valid |= VALID_BOTLINE|VALID_BOTLINE_AP;
  let g:a=strlen(substitute(@@, '[^ ]', '', 'g'))
  let g:opt=&linebreak
  let g:bufnr=bufnr('%')

Fixed code:
  let g:a = strlen(substitute(@@, '[^ ]', '', 'g'))
  let g:opt = &linebreak
  let g:bufnr = bufnr('%')
func Test_scroll_in_ex_mode()
  " This was using invalid memory because w_botline was invalid.
  let lines =<< trim END
      diffsplit
      norm os00(
      call writefile(['done'], 'Xdone')
      qa!
  END
  call writefile(lines, 'Xscript')
  call assert_equal(1, RunVim([], [], '--clean -X -Z -e -s -S Xscript'))
  call assert_equal(['done'], readfile('Xdone'))

  call delete('Xscript')
  call delete('Xdone')
endfunc

/**/
    3564,
CVE-2021-3973 (C, published 2021-11-19T12:15Z)
Description: value: vim is vulnerable to Heap-based Buffer Overflow
Severity: HIGH (CVSS v3 base score: 7.8)
Weakness: CWE-122 \u2014 Heap-based Buffer Overflow
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().
Repository: https://github.com/vim/vim
Files changed:
src/findfile.c
src/normal.c
src/testdir/test_visual.vim
src/version.c
Commit message: patch 8.2.3611: crash when using CTRL-W f without finding a file name

Problem:    Crash when using CTRL-W f without finding a file name.
Solution:   Bail out when the file name length is zero.


Vulnerable code:
	if (has_mbyte)
	    // Correct the length to include the whole last character.

Fixed code:
    if (len == 0)
	return NULL;

# endif
    if (len == 0)
	return NULL;

# if defined(FEAT_FIND_ID) && defined(FEAT_EVAL)
	if (**pp == NUL)
	    *lenp = 0;
	if (has_mbyte && *lenp > 0)
	    // Correct the length to include all bytes of the last character.
func Test_visual_block_ctrl_w_f()
  " Emtpy block selected in new buffer should not result in an error.
  au! BufNew foo sil norm f
  edit foo

  au! BufNew
endfunc

/**/
    3611,
CVE-2021-3984 (C, published 2021-12-01T11:15Z)
Description: value: vim is vulnerable to Heap-based Buffer Overflow
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-122 \u2014 Heap-based Buffer Overflow
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().
Repository: https://github.com/vim/vim
Files changed:
src/cindent.c
src/testdir/test_cindent.vim
src/version.c
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.


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 (C, published 2021-12-01T10:15Z)
Description: value: vim is vulnerable to Heap-based Buffer Overflow
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-122 \u2014 Heap-based Buffer Overflow
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().
Repository: https://github.com/vim/vim
Files changed:
src/help.c
src/testdir/test_help.vim
src/version.c
Commit message: patch 8.2.3669: buffer overflow with long help argument

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


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-4069 (C, published 2021-12-06T12:15Z)
Description: value: vim is vulnerable to Use After Free
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/vim/vim
Files changed:
src/ex_docmd.c
src/testdir/test_ex_mode.vim
src/version.c
Commit message: patch 8.2.3741: using freed memory in open command

Problem:    Using freed memory in open command.
Solution:   Make a copy of the current line.


Vulnerable code:
	    p = ml_get_curline();
	    if (vim_regexec(&regmatch, p, (colnr_T)0))
		curwin->w_cursor.col = (colnr_T)(regmatch.startp[0] - p);

Fixed code:
	    // make a copy of the line, when searching for a mark it might be
	    // flushed
	    char_u *line = vim_strsave(ml_get_curline());

	    if (vim_regexec(&regmatch, line, (colnr_T)0))
		curwin->w_cursor.col = (colnr_T)(regmatch.startp[0] - line);
	    vim_free(line);
func Test_open_command_flush_line()
  " this was accessing freed memory: the regexp match uses a pointer to the
  " current line which becomes invalid when searching for the ') mark.
  new
  call setline(1, ['one', 'two. three'])
  s/one/ONE
  try
    open /\%')/
  catch /E479/
  endtry
  bwipe!
endfunc

/**/
    3741,
CVE-2021-4166 (C, published 2021-12-25T19:15Z)
Description: value: vim is vulnerable to Out-of-bounds Read
Severity: MEDIUM (CVSS v3 base score: 7.1)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/vim/vim
Files changed:
src/arglist.c
src/testdir/test_arglist.vim
src/version.c
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".


Vulnerable code:

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-4187 (C, published 2021-12-29T17:15Z)
Description: value: vim is vulnerable to Use After Free
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/vim/vim
Files changed:
src/testdir/test_vim9_func.vim
src/userfunc.c
src/version.c
Commit message: patch 8.2.3923: Vim9: double free with split argument list in nested function

Problem:    Vim9: double free if a nested function has a line break in the
            argument list.
Solution:   Set cmdlinep when freeing the previous line.


Vulnerable code:
def Test_nested_functin_with_nextcmd()

Fixed code:
def Test_nested_function_with_nextcmd()
def Test_nested_function_with_args_split()
  var lines =<< trim END
      vim9script
      def FirstFunction()
        def SecondFunction(
        )
        # had a double free if the right parenthesis of the nested function is
        # on the next line
         
        enddef|BBBB
      enddef
      # Compile all functions
      defcompile
  END
  # FIXME: this should fail on the BBBB
  CheckScriptSuccess(lines)
enddef

	    if (*eap->cmdlinep == *line_to_free)
		*eap->cmdlinep = theline;
/**/
    3923,
CVE-2021-4192 (C, published 2021-12-31T15:15Z)
Description: value: vim is vulnerable to Use After Free
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-416 \u2014 Use After Free
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.
Repository: https://github.com/vim/vim
Files changed:
src/regexp.c
src/testdir/test_regexp_latin.vim
src/version.c
Commit message: patch 8.2.3949: using freed memory with /\%V

Problem:    Using freed memory with /\%V.
Solution:   Get the line again after getvvcol().


Vulnerable code:
	col = (colnr_T)(rex.input - rex.line);
	cols = win_linetabsize(wp, rex.line, (colnr_T)(rex.input - rex.line));

Fixed code:
    col = (colnr_T)(rex.input - rex.line);

	// getvvcol() flushes rex.line, need to get it again
	rex.line = reg_getline(rex.lnum);
	rex.input = rex.line + col;

	cols = win_linetabsize(wp, rex.line, col);
func Test_using_visual_position()
  " this was using freed memory
  new
  exe "norm 0o\<Esc>\<C-V>k\<C-X>o0"
  /\%V
  bwipe!
endfunc

/**/
    3949,
CVE-2021-4193 (C, published 2021-12-31T16:15Z)
Description: value: vim is vulnerable to Out-of-bounds Read
Severity: MEDIUM (CVSS v3 base score: 5.5)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/vim/vim
Files changed:
src/charset.c
src/testdir/test_regexp_latin.vim
src/version.c
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().


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-0128 (C, published 2022-01-06T17:15Z)
Description: value: vim is vulnerable to Out-of-bounds Read
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/vim/vim
Files changed:
src/ex_docmd.c
src/testdir/test_vim9_func.vim
src/version.c
src/vim9compile.c
Commit message: patch 8.2.4009: reading one byte beyond the end of the line

Problem:    Reading one byte beyond the end of the line.
Solution:   Check for NUL byte first.


Vulnerable code:
	if (p == eap->cmd && p[0] == p[1] && (*p == '+' || *p == '-'))
		       || (cmd[0] == cmd[1] && (*cmd == '+' || *cmd == '-')))))

Fixed code:
	if (p == eap->cmd && p[0] != NUL && p[0] == p[1]
						   && (*p == '+' || *p == '-'))
def Test_go_beyond_end_of_cmd()
  # this was reading the byte after the end of the line
  var lines =<< trim END
    def F()
      cal
    enddef
    defcompile
  END
  CheckScriptFailure(lines, 'E476:')
enddef

/**/
    4009,
		       || (cmd[0] != NUL && cmd[0] == cmd[1]
					    && (*cmd == '+' || *cmd == '-')))))