From b793395019333127e085997b7ced4ea02053697e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 27 Oct 2022 11:43:10 +0800 Subject: [PATCH 1/3] vim-patch:8.2.4070: using uninitialized memory when reading empty file MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem: Using uninitialized memory when reading empty file. Solution: Check for empty file before checking for NL. (Dominique Pellé, closes vim/vim#9511) https://github.com/vim/vim/commit/f5d639a8af719eb8ecb141b5c0890627e4d83134 Co-authored-by: Dominique Pelle --- src/nvim/eval/funcs.c | 2 +- src/nvim/testdir/test_eval_stuff.vim | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c index f66ff7b5bb..b475ff1096 100644 --- a/src/nvim/eval/funcs.c +++ b/src/nvim/eval/funcs.c @@ -5921,7 +5921,7 @@ static void f_readfile(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) for (p = buf, start = buf; p < buf + readlen || (readlen <= 0 && (prevlen > 0 || binary)); p++) { - if (*p == '\n' || readlen <= 0) { + if (readlen <= 0 || *p == '\n') { char *s = NULL; size_t len = (size_t)(p - start); diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim index dc110af356..5c60b64c22 100644 --- a/src/nvim/testdir/test_eval_stuff.vim +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -120,6 +120,13 @@ func Test_readfile_binary() call delete('XReadfile_bin') endfunc +func Test_readfile_binary_empty() + call writefile([], 'Xempty-file') + " This used to compare uninitialized memory in Vim <= 8.2.4065 + call assert_equal([''], readfile('Xempty-file', 'b')) + call delete('Xempty-file') +endfunc + func Test_readfile_bom() call writefile(["\ufeffFOO", "FOO\ufeffBAR"], 'XReadfile_bom') call assert_equal(['FOO', 'FOOBAR'], readfile('XReadfile_bom')) From 807c6bb909806b5abc3e46a9677bedfdddf2a7f0 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 27 Oct 2022 11:40:38 +0800 Subject: [PATCH 2/3] vim-patch:8.2.4206: condition with many "(" causes a crash Problem: Condition with many "(" causes a crash. Solution: Limit recursion to 1000. https://github.com/vim/vim/commit/fe6fb267e6ee5c5da2f41889e4e0e0ac5bf4b89d Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 12 ++++++++++++ src/nvim/testdir/test_eval_stuff.vim | 5 +++++ 2 files changed, 17 insertions(+) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 8bd91ec9a2..42ea8bd79b 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -65,6 +65,7 @@ static char *e_nowhitespace = N_("E274: No white space allowed before parenthesis"); static char *e_write2 = N_("E80: Error while writing: %s"); static char *e_string_list_or_blob_required = N_("E1098: String, List or Blob required"); +static char e_expression_too_recursive_str[] = N_("E1169: Expression too recursive: %s"); static char * const namespace_char = "abglstvw"; @@ -2911,6 +2912,7 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) const char *start_leader, *end_leader; int ret = OK; char *alias; + static int recurse = 0; // Initialise variable so that tv_clear() can't mistake this for a // string and free a string that isn't there. @@ -2923,6 +2925,14 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) } end_leader = *arg; + // Limit recursion to 1000 levels. At least at 10000 we run out of stack + // and crash. + if (recurse == 1000) { + semsg(_(e_expression_too_recursive_str), *arg); + return FAIL; + } + recurse++; + switch (**arg) { // Number constant. case '0': @@ -3127,6 +3137,8 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) if (ret == OK && evaluate && end_leader > start_leader) { ret = eval7_leader(rettv, (char *)start_leader, &end_leader); } + + recurse--; return ret; } diff --git a/src/nvim/testdir/test_eval_stuff.vim b/src/nvim/testdir/test_eval_stuff.vim index 5c60b64c22..851048ec5b 100644 --- a/src/nvim/testdir/test_eval_stuff.vim +++ b/src/nvim/testdir/test_eval_stuff.vim @@ -367,6 +367,11 @@ func Test_curly_assignment() unlet g:gvar endfunc +func Test_deep_recursion() + " this was running out of stack + call assert_fails("exe 'if ' .. repeat('(', 1002)", 'E1169: Expression too recursive: ((') +endfunc + " K_SPECIAL in the modified character used be escaped, which causes " double-escaping with feedkeys() or as the return value of an mapping, " and doesn't match what getchar() returns, From e3acf913db7eb27d53ea8f91b70fb2c723796be9 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 27 Oct 2022 11:50:08 +0800 Subject: [PATCH 3/3] vim-patch:8.2.4207: recursion test fails with MSVC Problem: Recursion test fails with MSVC. Solution: Use a smaller limit for MSVC. https://github.com/vim/vim/commit/50e05254450954f04183efc7bc871527a67868b8 Co-authored-by: Bram Moolenaar --- src/nvim/eval.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/nvim/eval.c b/src/nvim/eval.c index 42ea8bd79b..0e4dbeaea6 100644 --- a/src/nvim/eval.c +++ b/src/nvim/eval.c @@ -2926,8 +2926,14 @@ static int eval7(char **arg, typval_T *rettv, int evaluate, int want_string) end_leader = *arg; // Limit recursion to 1000 levels. At least at 10000 we run out of stack - // and crash. - if (recurse == 1000) { + // and crash. With MSVC the stack is smaller. + if (recurse == +#ifdef _MSC_VER + 300 +#else + 1000 +#endif + ) { semsg(_(e_expression_too_recursive_str), *arg); return FAIL; }