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
|
From: Markus Koschany <apo@debian.org>
Date: Wed, 26 Oct 2022 23:16:08 +0200
Subject: CVE-2022-0408
Origin: https://github.com/vim/vim/commit/06f15416bb8d5636200a10776f1752c4d6e49f31
---
src/spell.c | 17 +++++++++++++++--
src/testdir/test_spell.vim | 10 ++++++++++
2 files changed, 25 insertions(+), 2 deletions(-)
--- a/src/spell.c
+++ b/src/spell.c
@@ -4191,7 +4191,7 @@ suggest_try_change(suginfo_T *su)
/* Check the maximum score, if we go over it we won't try this change. */
#define TRY_DEEPER(su, stack, depth, add) \
- (stack[depth].ts_score + (add) < su->su_maxscore)
+ (depth < MAXWLEN && stack[depth].ts_score + (add) < su->su_maxscore)
/*
* Try finding suggestions by adding/removing/swapping letters.
@@ -4263,6 +4263,9 @@ suggest_trie_walk(
char_u changename[MAXWLEN][80];
#endif
int breakcheckcount = 1000;
+#ifdef FEAT_RELTIME
+ proftime_T time_limit;
+#endif
int compound_ok;
/*
@@ -4311,6 +4314,11 @@ suggest_trie_walk(
sp->ts_state = STATE_START;
}
}
+#ifdef FEAT_RELTIME
+ // The loop may take an indefinite amount of time. Break out after five
+ // sectonds. TODO: add an option for the time limit.
+ profile_setlimit(5000, &time_limit);
+#endif
/*
* Loop to find all suggestions. At each round we either:
@@ -4349,7 +4357,8 @@ suggest_trie_walk(
/* At end of a prefix or at start of prefixtree: check for
* following word. */
- if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX)
+ if (depth < MAXWLEN
+ && (byts[arridx] == 0 || n == (int)STATE_NOPREFIX))
{
/* Set su->su_badflags to the caps type at this position.
* Use the caps type until here for the prefix itself. */
@@ -5656,6 +5665,10 @@ suggest_trie_walk(
{
ui_breakcheck();
breakcheckcount = 1000;
+#ifdef FEAT_RELTIME
+ if (profile_passed_limit(&time_limit))
+ got_int = TRUE;
+#endif
}
}
}
--- a/src/testdir/test_spell.vim
+++ b/src/testdir/test_spell.vim
@@ -388,6 +388,16 @@ func Test_zeq_crash()
bwipe!
endfunc
+func Test_spellsuggest_too_deep()
+ " This was incrementing "depth" over MAXWLEN.
+ new
+ set spell
+ norm s000G00�000000000000
+ sil norm ..vzG................vvzG0 v z=
+ set nospell
+ bwipe!
+endfunc
+
func LoadAffAndDic(aff_contents, dic_contents)
set enc=latin1
set spellfile=
|