Patch 9.0.0286
Problem:    Using freed memory when location list changed in autocmd.
Solution:   Return QF_ABORT and handle it. (Yegappan Lakshmanan,
            closes #10993)
Files:      src/quickfix.c, src/testdir/test_quickfix.vim


*** ../vim-9.0.0285/src/quickfix.c      2022-08-24 20:07:19.342558427 +0100
--- src/quickfix.c      2022-08-27 20:56:11.908359958 +0100
***************
*** 594,599 ****
--- 594,600 ----
      QF_NOMEM = 3,
      QF_IGNORE_LINE = 4,
      QF_MULTISCAN = 5,
+     QF_ABORT = 6
  };
  
  /*
***************
*** 3153,3159 ****
  /*
   * Edit the selected file or help file.
   * Returns OK if successfully edited the file, FAIL on failing to open the
!  * buffer and NOTDONE if the quickfix/location list was freed by an autocmd
   * when opening the buffer.
   */
      static int
--- 3154,3160 ----
  /*
   * Edit the selected file or help file.
   * Returns OK if successfully edited the file, FAIL on failing to open the
!  * buffer and QF_ABORT if the quickfix/location list was freed by an autocmd
   * when opening the buffer.
   */
      static int
***************
*** 3199,3212 ****
        {
            emsg(_(e_current_window_was_closed));
            *opened_window = FALSE;
!           return NOTDONE;
        }
      }
  
      if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid))
      {
        emsg(_(e_current_quickfix_list_was_changed));
!       return NOTDONE;
      }
  
      // Check if the list was changed.  The pointers may happen to be 
identical,
--- 3200,3213 ----
        {
            emsg(_(e_current_window_was_closed));
            *opened_window = FALSE;
!           return QF_ABORT;
        }
      }
  
      if (qfl_type == QFLT_QUICKFIX && !qflist_valid(NULL, save_qfid))
      {
        emsg(_(e_current_quickfix_list_was_changed));
!       return QF_ABORT;
      }
  
      // Check if the list was changed.  The pointers may happen to be 
identical,
***************
*** 3219,3225 ****
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return NOTDONE;
      }
  
      return retval;
--- 3220,3226 ----
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return QF_ABORT;
      }
  
      return retval;
***************
*** 3317,3323 ****
   * a new window.
   * Returns OK if successfully jumped or opened a window. Returns FAIL if not
   * able to jump/open a window.  Returns NOTDONE if a file is not associated
!  * with the entry.
   */
      static int
  qf_jump_open_window(
--- 3318,3325 ----
   * a new window.
   * Returns OK if successfully jumped or opened a window. Returns FAIL if not
   * able to jump/open a window.  Returns NOTDONE if a file is not associated
!  * with the entry.  Returns QF_ABORT if the quickfix/location list was 
modified
!  * by an autocmd.
   */
      static int
  qf_jump_open_window(
***************
*** 3344,3350 ****
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return FAIL;
      }
  
      // If currently in the quickfix window, find another window to show the
--- 3346,3352 ----
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return QF_ABORT;
      }
  
      // If currently in the quickfix window, find another window to show the
***************
*** 3368,3374 ****
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return FAIL;
      }
  
      return OK;
--- 3370,3376 ----
            emsg(_(e_current_quickfix_list_was_changed));
        else
            emsg(_(e_current_location_list_was_changed));
!       return QF_ABORT;
      }
  
      return OK;
***************
*** 3379,3385 ****
   * particular line/column, adjust the folds and display a message about the
   * jump.
   * Returns OK on success and FAIL on failing to open the file/buffer.  Returns
!  * NOTDONE if the quickfix/location list is freed by an autocmd when opening
   * the file.
   */
      static int
--- 3381,3387 ----
   * particular line/column, adjust the folds and display a message about the
   * jump.
   * Returns OK on success and FAIL on failing to open the file/buffer.  Returns
!  * QF_ABORT if the quickfix/location list is freed by an autocmd when opening
   * the file.
   */
      static int
***************
*** 3508,3521 ****
      retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window);
      if (retval == FAIL)
        goto failed;
      if (retval == NOTDONE)
        goto theend;
  
      retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid,
                                  &opened_window, old_KeyTyped, print_message);
!     if (retval == NOTDONE)
      {
!       // Quickfix/location list is freed by an autocmd
        qi = NULL;
        qf_ptr = NULL;
      }
--- 3510,3529 ----
      retval = qf_jump_open_window(qi, qf_ptr, newwin, &opened_window);
      if (retval == FAIL)
        goto failed;
+     if (retval == QF_ABORT)
+     {
+       qi = NULL;
+       qf_ptr = NULL;
+       goto theend;
+     }
      if (retval == NOTDONE)
        goto theend;
  
      retval = qf_jump_to_buffer(qi, qf_index, qf_ptr, forceit, prev_winid,
                                  &opened_window, old_KeyTyped, print_message);
!     if (retval == QF_ABORT)
      {
!       // Quickfix/location list was modified by an autocmd
        qi = NULL;
        qf_ptr = NULL;
      }
*** ../vim-9.0.0285/src/testdir/test_quickfix.vim       2022-08-24 
20:07:19.342558427 +0100
--- src/testdir/test_quickfix.vim       2022-08-27 20:56:11.908359958 +0100
***************
*** 6363,6367 ****
--- 6363,6384 ----
    cclose
  endfunc
  
+ " Test for replacing the location list from an autocmd. This used to cause a
+ " read from freed memory.
+ func Test_loclist_replace_autocmd()
+   %bw!
+   call setloclist(0, [], 'f')
+   let s:bufnr = bufnr()
+   cal setloclist(0, [{'0': 0, '': ''}])
+   au BufEnter * cal setloclist(1, [{'t': ''}, {'bufnr': s:bufnr}], 'r')
+   lopen
+   try
+     exe "norm j\<CR>"
+   catch
+   endtry
+   lnext
+   %bw!
+   call setloclist(0, [], 'f')
+ endfunc
  
  " vim: shiftwidth=2 sts=2 expandtab
*** ../vim-9.0.0285/src/version.c       2022-08-27 12:22:19.979008597 +0100
--- src/version.c       2022-08-27 16:58:13.441095567 +0100
***************
*** 709,710 ****
--- 709,712 ----
  {   /* Add new patch number below this line */
+ /**/
+     286,
  /**/

-- 
"I know that there are people who don't love their fellow man,
and I hate those people!" - Tom Lehrer

 /// Bram Moolenaar -- [email protected] -- http://www.Moolenaar.net   \\\
///                                                                      \\\
\\\        sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ ///
 \\\            help me help AIDS victims -- http://ICCF-Holland.org    ///

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/20220827200029.CE5511C066C%40moolenaar.net.

Raspunde prin e-mail lui