aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-04-04 11:11:37 +0800
committerGitHub <noreply@github.com>2022-04-04 11:11:37 +0800
commitdb13f105d62e868997e61d8cef921fbebb312ddc (patch)
tree5d860ba78b78cf27fb542cb253614a83b8b5d87b
parenta973fa5b4397933e94d888d06e435a986fc4a218 (diff)
parent683648a396a804a8d54731283d525f0c34193361 (diff)
downloadrneovim-db13f105d62e868997e61d8cef921fbebb312ddc.tar.gz
rneovim-db13f105d62e868997e61d8cef921fbebb312ddc.tar.bz2
rneovim-db13f105d62e868997e61d8cef921fbebb312ddc.zip
Merge pull request #17988 from zeertzjq/vim-8.2.4247
vim-patch:8.2.{4247,4258}: stack corruption when looking for spell suggestions
-rw-r--r--src/nvim/spell.c11
-rw-r--r--src/nvim/testdir/test_spell.vim12
2 files changed, 19 insertions, 4 deletions
diff --git a/src/nvim/spell.c b/src/nvim/spell.c
index 97f39c925a..2d617bba4b 100644
--- a/src/nvim/spell.c
+++ b/src/nvim/spell.c
@@ -3690,7 +3690,7 @@ static void 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 - 1 && (stack)[depth].ts_score + (add) < (su)->su_maxscore)
// Try finding suggestions by adding/removing/swapping letters.
//
@@ -3794,6 +3794,10 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
}
}
+ // The loop may take an indefinite amount of time. Break out after five
+ // sectonds. TODO(vim): add an option for the time limit.
+ proftime_T time_limit = profile_setlimit(5000);
+
// Loop to find all suggestions. At each round we either:
// - For the current state try one operation, advance "ts_curi",
// increase "depth".
@@ -3824,7 +3828,7 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
// At end of a prefix or at start of prefixtree: check for
// following word.
- if (byts[arridx] == 0 || n == STATE_NOPREFIX) {
+ if (depth < MAXWLEN - 1 && (byts[arridx] == 0 || n == STATE_NOPREFIX)) {
// Set su->su_badflags to the caps type at this position.
// Use the caps type until here for the prefix itself.
n = nofold_len(fword, sp->ts_fidx, su->su_badptr);
@@ -4927,6 +4931,9 @@ static void suggest_trie_walk(suginfo_T *su, langp_T *lp, char_u *fword, bool so
if (--breakcheckcount == 0) {
os_breakcheck();
breakcheckcount = 1000;
+ if (profile_passed_limit(time_limit)) {
+ got_int = true;
+ }
}
}
}
diff --git a/src/nvim/testdir/test_spell.vim b/src/nvim/testdir/test_spell.vim
index 1ecb5c8070..56ed97cdd9 100644
--- a/src/nvim/testdir/test_spell.vim
+++ b/src/nvim/testdir/test_spell.vim
@@ -407,7 +407,7 @@ func Test_zz_basic()
\ )
call assert_equal("gebletegek", soundfold('goobledygoook'))
- call assert_equal("kepereneven", 'kóopërÿnôven'->soundfold())
+ call assert_equal("kepereneven", 'kóopërÿnôven'->soundfold())
call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
endfunc
@@ -588,7 +588,7 @@ func Test_zz_sal_and_addition()
mkspell! Xtest Xtest
set spl=Xtest.latin1.spl spell
call assert_equal('kbltykk', soundfold('goobledygoook'))
- call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
+ call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
"also use an addition file
@@ -681,6 +681,14 @@ func Test_spell_long_word()
set nospell
endfunc
+func Test_spellsuggest_too_deep()
+ " This was incrementing "depth" over MAXWLEN.
+ new
+ norm s000G00ý000000000000
+ sil norm ..vzG................vvzG0 v z=
+ bwipe!
+endfunc
+
func LoadAffAndDic(aff_contents, dic_contents)
throw 'skipped: Nvim does not support enc=latin1'
set enc=latin1