summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2018-03-11 11:40:26 +1100
committerMaxime Coste <mawww@kakoune.org>2018-03-11 11:44:10 +1100
commite66073bc94cad6c13c2f6c35d5e3d794f6a00a2c (patch)
tree32a55174b5cc140256a085e54fcff6b6a1948841
parent4584ecac776492cfff1b48a5c47099eb470b5c50 (diff)
Detect infinit recursion in reference highlighting
Reference highlighters allow for potential mutual recursion between highlighters. This is usually fine, but if the recursion happens on the same buffer range, it means we will recurse infinitely. Fixes #1920
-rw-r--r--src/highlighters.cc8
-rw-r--r--test/regression/1920-crash-on-python-in-docstring/cmd1
-rw-r--r--test/regression/1920-crash-on-python-in-docstring/display6
-rw-r--r--test/regression/1920-crash-on-python-in-docstring/in1
-rw-r--r--test/regression/1920-crash-on-python-in-docstring/rc3
5 files changed, 19 insertions, 0 deletions
diff --git a/src/highlighters.cc b/src/highlighters.cc
index 41953aa4..864c7449 100644
--- a/src/highlighters.cc
+++ b/src/highlighters.cc
@@ -1581,6 +1581,14 @@ struct ReferenceHighlighter : Highlighter
private:
void do_highlight(HighlightContext context, DisplayBuffer& display_buffer, BufferRange range) override
{
+ static Vector<std::pair<StringView, BufferRange>> running_refs;
+ const std::pair<StringView, BufferRange> desc{m_name, range};
+ if (contains(running_refs, desc))
+ return write_to_debug_buffer(format("highlighting recursion detected with ref to {}", m_name));
+
+ running_refs.push_back(desc);
+ auto pop_desc = on_scope_end([] { running_refs.pop_back(); });
+
try
{
DefinedHighlighters::instance().get_child(m_name).highlight(context, display_buffer, range);
diff --git a/test/regression/1920-crash-on-python-in-docstring/cmd b/test/regression/1920-crash-on-python-in-docstring/cmd
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/test/regression/1920-crash-on-python-in-docstring/cmd
@@ -0,0 +1 @@
+
diff --git a/test/regression/1920-crash-on-python-in-docstring/display b/test/regression/1920-crash-on-python-in-docstring/display
new file mode 100644
index 00000000..c74fa31e
--- /dev/null
+++ b/test/regression/1920-crash-on-python-in-docstring/display
@@ -0,0 +1,6 @@
+{ "jsonrpc": "2.0", "method": "draw", "params": [[[{ "face": { "fg": "black", "bg": "white", "attributes": [] }, "contents": "\"" }, { "face": { "fg": "magenta", "bg": "default", "attributes": [] }, "contents": "\"\">>> " }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "\"\"\"\u000a" }]], { "fg": "default", "bg": "default", "attributes": [] }, { "fg": "blue", "bg": "default", "attributes": [] }] }
+{ "jsonrpc": "2.0", "method": "menu_hide", "params": [] }
+{ "jsonrpc": "2.0", "method": "info_hide", "params": [] }
+{ "jsonrpc": "2.0", "method": "draw_status", "params": [[], [{ "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": "out 1:1 " }, { "face": { "fg": "black", "bg": "yellow", "attributes": [] }, "contents": "" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " " }, { "face": { "fg": "blue", "bg": "default", "attributes": [] }, "contents": "1 sel" }, { "face": { "fg": "default", "bg": "default", "attributes": [] }, "contents": " - unnamed0@[kak-tests]" }], { "fg": "cyan", "bg": "default", "attributes": [] }] }
+{ "jsonrpc": "2.0", "method": "set_cursor", "params": ["buffer", { "line": 0, "column": 0 }] }
+{ "jsonrpc": "2.0", "method": "refresh", "params": [true] }
diff --git a/test/regression/1920-crash-on-python-in-docstring/in b/test/regression/1920-crash-on-python-in-docstring/in
new file mode 100644
index 00000000..2a40350c
--- /dev/null
+++ b/test/regression/1920-crash-on-python-in-docstring/in
@@ -0,0 +1 @@
+""">>> """
diff --git a/test/regression/1920-crash-on-python-in-docstring/rc b/test/regression/1920-crash-on-python-in-docstring/rc
new file mode 100644
index 00000000..909f53ff
--- /dev/null
+++ b/test/regression/1920-crash-on-python-in-docstring/rc
@@ -0,0 +1,3 @@
+source "%val{runtime}/colors/default.kak"
+source "%val{runtime}/rc/core/python.kak"
+set buffer filetype python