1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
From: Markus Koschany <apo@debian.org>
Date: Wed, 2 Nov 2022 22:11:50 +0100
Subject: CVE_2022-1968
Origin: https://github.com/vim/vim/commit/409510c588b1eec1ae33511ae97a21eb8e110895
---
src/search.c | 21 ++++++++++++++++++---
src/testdir/test_tagjump.vim | 12 ++++++++++++
2 files changed, 30 insertions(+), 3 deletions(-)
diff --git a/src/search.c b/src/search.c
index 4b3f853..9a17918 100644
--- a/src/search.c
+++ b/src/search.c
@@ -4852,6 +4852,21 @@ linewhite(linenr_T lnum)
#endif
#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.
@@ -4958,7 +4973,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 (;;)
{
@@ -5296,7 +5311,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))
@@ -5511,7 +5526,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 da4af2f..7605730 100644
--- a/src/testdir/test_tagjump.vim
+++ b/src/testdir/test_tagjump.vim
@@ -372,4 +372,16 @@ func Test_getsettagstack()
set tags&
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
|