From 409510c588b1eec1ae33511ae97a21eb8e110895 Mon Sep 17 00:00:00 2001
From: Bram Moolenaar <Bram@vim.org>
Date: Wed, 1 Jun 2022 15:23:13 +0100
Subject: [PATCH] patch 8.2.5050: using freed memory when searching for pattern
 in path

Problem:    Using freed memory when searching for pattern in path.
Solution:   Make a copy of the line.
---
 src/search.c                 | 21 ++++++++++++++++++---
 src/testdir/test_tagjump.vim | 11 +++++++++++
 2 files changed, 29 insertions(+), 3 deletions(-)

diff --git a/src/search.c b/src/search.c
index 75f0c59..701a8ed 100644
--- a/src/search.c
+++ b/src/search.c
@@ -5143,6 +5143,21 @@ search_stat(
 }
 
 #if defined(FEAT_FIND_ID) || defined(PROTO)
+
+/*
+ * Get line "lnum" and copy it into "buf[LSIZE]".
+ * The copy is made because the regexp may make the line invalid when using a
+ * mark.
+ */
+    static char_u *
+get_line_and_copy(linenr_T lnum, char_u *buf)
+{
+    char_u *line = ml_get(lnum);
+
+    vim_strncpy(buf, line, LSIZE - 1);
+    return buf;
+}
+
 /*
  * Find identifiers or defines in included files.
  * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase.
@@ -5245,7 +5260,7 @@ find_pattern_in_path(
 	end_lnum = curbuf->b_ml.ml_line_count;
     if (lnum > end_lnum)		// do at least one line
 	lnum = end_lnum;
-    line = ml_get(lnum);
+    line = get_line_and_copy(lnum, file_line);
 
     for (;;)
     {
@@ -5573,7 +5588,7 @@ search_line:
 		    {
 			if (lnum >= end_lnum)
 			    goto exit_matched;
-			line = ml_get(++lnum);
+			line = get_line_and_copy(++lnum, file_line);
 		    }
 		    else if (vim_fgets(line = file_line,
 						      LSIZE, files[depth].fp))
@@ -5783,7 +5798,7 @@ exit_matched:
 	{
 	    if (++lnum > end_lnum)
 		break;
-	    line = ml_get(lnum);
+	    line = get_line_and_copy(lnum, file_line);
 	}
 	already = NULL;
     }
diff --git a/src/testdir/test_tagjump.vim b/src/testdir/test_tagjump.vim
index 0eb9491..9e08a49 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -571,4 +571,15 @@ func Test_define_search()
   bwipe!
 endfunc
 
+" this was using a line from ml_get() freed by the regexp
+func Test_isearch_copy_line()
+  new
+  norm o
+  norm 0
+  0norm o
+  sil! norm bc0
+  sil! isearch \%')
+  bwipe!
+endfunc
+
 " vim: shiftwidth=2 sts=2 expandtab
-- 
1.8.3.1

