79 lines
2.3 KiB
Diff
79 lines
2.3 KiB
Diff
From: Bram Moolenaar <Bram@vim.org>
|
|
Date: Mon, 24 Jan 2022 18:16:12 +0000
|
|
Subject: [PATCH] patch 8.2.4206: condition with many "(" causes a crash
|
|
|
|
Problem: Condition with many "(" causes a crash.
|
|
Solution: Limit recursion to 1000.
|
|
---
|
|
src/eval.c | 12 ++++++++++++
|
|
src/globals.h | 2 ++
|
|
src/testdir/test_eval_stuff.vim | 5 +++++
|
|
3 files changed, 19 insertions(+)
|
|
|
|
diff --git a/src/eval.c b/src/eval.c
|
|
index 3b563f7..95dda90 100644
|
|
--- a/src/eval.c
|
|
+++ b/src/eval.c
|
|
@@ -2495,6 +2495,7 @@ eval7(
|
|
char_u *start_leader, *end_leader;
|
|
int ret = OK;
|
|
char_u *alias;
|
|
+ static int recurse = 0;
|
|
|
|
/*
|
|
* Initialise variable so that clear_tv() can't mistake this for a
|
|
@@ -2521,6 +2522,15 @@ eval7(
|
|
return FAIL;
|
|
}
|
|
|
|
+ // 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)
|
|
{
|
|
/*
|
|
@@ -2761,6 +2771,8 @@ eval7(
|
|
*/
|
|
if (ret == OK && evaluate && end_leader > start_leader)
|
|
ret = eval7_leader(rettv, start_leader, &end_leader);
|
|
+
|
|
+ --recurse;
|
|
return ret;
|
|
}
|
|
|
|
diff --git a/src/globals.h b/src/globals.h
|
|
index 75092b7..659bad6 100644
|
|
--- a/src/globals.h
|
|
+++ b/src/globals.h
|
|
@@ -1464,6 +1464,8 @@ EXTERN char e_endwhile[] INIT(= N_("E170: Missing :endwhile"));
|
|
EXTERN char e_endfor[] INIT(= N_("E170: Missing :endfor"));
|
|
EXTERN char e_while[] INIT(= N_("E588: :endwhile without :while"));
|
|
EXTERN char e_for[] INIT(= N_("E588: :endfor without :for"));
|
|
+EXTERN char e_expression_too_recursive_str[]
|
|
+ INIT(= N_("E1169: Expression too recursive: %s"));
|
|
#endif
|
|
EXTERN char e_exists[] INIT(= N_("E13: File exists (add ! to override)"));
|
|
EXTERN char e_failed[] INIT(= N_("E472: Command failed"));
|
|
diff --git a/src/testdir/test_eval_stuff.vim b/src/testdir/test_eval_stuff.vim
|
|
index ec566da..32a5411 100644
|
|
--- a/src/testdir/test_eval_stuff.vim
|
|
+++ b/src/testdir/test_eval_stuff.vim
|
|
@@ -216,3 +216,8 @@ func Test_scriptversion_fail()
|
|
call assert_fails('source Xversionscript', 'E999:')
|
|
call delete('Xversionscript')
|
|
endfunc
|
|
+
|
|
+func Test_deep_recursion()
|
|
+ " this was running out of stack
|
|
+ call assert_fails("exe 'if ' .. repeat('(', 1002)", 'E1169: Expression too recursive: ((')
|
|
+endfunc
|
|
--
|
|
1.8.3.1
|
|
|