93 lines
2.8 KiB
Diff
93 lines
2.8 KiB
Diff
|
|
From 06f15416bb8d5636200a10776f1752c4d6e49f31 Mon Sep 17 00:00:00 2001
|
|||
|
|
From: Bram Moolenaar <Bram@vim.org>
|
|||
|
|
Date: Sat, 29 Jan 2022 10:51:59 +0000
|
|||
|
|
Subject: [PATCH] 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.
|
|||
|
|
---
|
|||
|
|
src/spellsuggest.c | 17 +++++++++++++++--
|
|||
|
|
src/testdir/test_spell.vim | 8 ++++++++
|
|||
|
|
2 files changed, 23 insertions(+), 2 deletions(-)
|
|||
|
|
|
|||
|
|
diff --git a/src/spellsuggest.c b/src/spellsuggest.c
|
|||
|
|
index 8615d52..a73e695 100644
|
|||
|
|
--- a/src/spellsuggest.c
|
|||
|
|
+++ b/src/spellsuggest.c
|
|||
|
|
@@ -1187,7 +1187,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.
|
|||
|
|
@@ -1259,6 +1259,9 @@ suggest_trie_walk(
|
|||
|
|
char_u changename[MAXWLEN][80];
|
|||
|
|
#endif
|
|||
|
|
int breakcheckcount = 1000;
|
|||
|
|
+#ifdef FEAT_RELTIME
|
|||
|
|
+ proftime_T time_limit;
|
|||
|
|
+#endif
|
|||
|
|
int compound_ok;
|
|||
|
|
|
|||
|
|
// Go through the whole case-fold tree, try changes at each node.
|
|||
|
|
@@ -1303,6 +1306,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:
|
|||
|
|
// - For the current state try one operation, advance "ts_curi",
|
|||
|
|
@@ -1337,7 +1345,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.
|
|||
|
|
@@ -2630,6 +2639,10 @@ suggest_trie_walk(
|
|||
|
|
{
|
|||
|
|
ui_breakcheck();
|
|||
|
|
breakcheckcount = 1000;
|
|||
|
|
+#ifdef FEAT_RELTIME
|
|||
|
|
+ if (profile_passed_limit(&time_limit))
|
|||
|
|
+ got_int = TRUE;
|
|||
|
|
+#endif
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
diff --git a/src/testdir/test_spell.vim b/src/testdir/test_spell.vim
|
|||
|
|
index e435e91..271d034 100644
|
|||
|
|
--- a/src/testdir/test_spell.vim
|
|||
|
|
+++ b/src/testdir/test_spell.vim
|
|||
|
|
@@ -427,6 +427,14 @@ func Test_spell_long_word()
|
|||
|
|
set nospell
|
|||
|
|
endfunc
|
|||
|
|
|
|||
|
|
+func Test_spellsuggest_too_deep()
|
|||
|
|
+ " This was incrementing "depth" over MAXWLEN.
|
|||
|
|
+ new
|
|||
|
|
+ norm s000G00<30>000000000000
|
|||
|
|
+ sil norm ..vzG................vvzG0 v z=
|
|||
|
|
+ bwipe!
|
|||
|
|
+endfunc
|
|||
|
|
+
|
|||
|
|
func LoadAffAndDic(aff_contents, dic_contents)
|
|||
|
|
set enc=latin1
|
|||
|
|
set spellfile=
|
|||
|
|
--
|
|||
|
|
1.8.3.1
|
|||
|
|
|