Skip to content

Commit 06f1541

Browse files
committed
patch 8.2.4247: stack corruption when looking for spell suggestions
Problem: Stack corruption when looking for spell suggestions. Solution: Prevent the depth increased too much. Add a five second time limit to finding suggestions.
1 parent e96eea7 commit 06f1541

File tree

3 files changed

+25
-2
lines changed

3 files changed

+25
-2
lines changed

src/spellsuggest.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1205,7 +1205,7 @@ suggest_try_change(suginfo_T *su)
12051205

12061206
// Check the maximum score, if we go over it we won't try this change.
12071207
#define TRY_DEEPER(su, stack, depth, add) \
1208-
(stack[depth].ts_score + (add) < su->su_maxscore)
1208+
(depth < MAXWLEN && stack[depth].ts_score + (add) < su->su_maxscore)
12091209

12101210
/*
12111211
* Try finding suggestions by adding/removing/swapping letters.
@@ -1277,6 +1277,9 @@ suggest_trie_walk(
12771277
char_u changename[MAXWLEN][80];
12781278
#endif
12791279
int breakcheckcount = 1000;
1280+
#ifdef FEAT_RELTIME
1281+
proftime_T time_limit;
1282+
#endif
12801283
int compound_ok;
12811284

12821285
// Go through the whole case-fold tree, try changes at each node.
@@ -1321,6 +1324,11 @@ suggest_trie_walk(
13211324
sp->ts_state = STATE_START;
13221325
}
13231326
}
1327+
#ifdef FEAT_RELTIME
1328+
// The loop may take an indefinite amount of time. Break out after five
1329+
// sectonds. TODO: add an option for the time limit.
1330+
profile_setlimit(5000, &time_limit);
1331+
#endif
13241332

13251333
// Loop to find all suggestions. At each round we either:
13261334
// - For the current state try one operation, advance "ts_curi",
@@ -1355,7 +1363,8 @@ suggest_trie_walk(
13551363

13561364
// At end of a prefix or at start of prefixtree: check for
13571365
// following word.
1358-
if (byts[arridx] == 0 || n == (int)STATE_NOPREFIX)
1366+
if (depth < MAXWLEN
1367+
&& (byts[arridx] == 0 || n == (int)STATE_NOPREFIX))
13591368
{
13601369
// Set su->su_badflags to the caps type at this position.
13611370
// Use the caps type until here for the prefix itself.
@@ -2649,6 +2658,10 @@ suggest_trie_walk(
26492658
{
26502659
ui_breakcheck();
26512660
breakcheckcount = 1000;
2661+
#ifdef FEAT_RELTIME
2662+
if (profile_passed_limit(&time_limit))
2663+
got_int = TRUE;
2664+
#endif
26522665
}
26532666
}
26542667
}

src/testdir/test_spell.vim

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -773,6 +773,14 @@ func Test_spell_long_word()
773773
set nospell
774774
endfunc
775775

776+
func Test_spellsuggest_too_deep()
777+
" This was incrementing "depth" over MAXWLEN.
778+
new
779+
norm s000G00ý000000000000
780+
sil norm ..vzG................vvzG0 v z=
781+
bwipe!
782+
endfunc
783+
776784
func LoadAffAndDic(aff_contents, dic_contents)
777785
set enc=latin1
778786
set spellfile=

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -750,6 +750,8 @@ static char *(features[]) =
750750

751751
static int included_patches[] =
752752
{ /* Add new patch number below this line */
753+
/**/
754+
4247,
753755
/**/
754756
4246,
755757
/**/

0 commit comments

Comments
 (0)