summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2017-11-07 23:58:56 +0800
committerMaxime Coste <mawww@kakoune.org>2017-11-08 00:02:49 +0800
commit04993de68765d64e6da882e4fd055fdc07bd736b (patch)
tree18fc70a8ed9021685f382eecf533602b1d0ee28e
parentd45f16b6c813842690e06ca70102be345ce80596 (diff)
Fix pipe logic in the case where the selections were accessed in the cmdline
When using an env var that needed the selections in the pipe command line, say $kak_selection, the selection update code would run, modifying the selections to adapt to eventual changes. But the rest of the pipe logic was assuming the selections would not change, leading to bugs.
-rw-r--r--src/normal.cc12
-rw-r--r--test/regression/0-crash-on-pipe-with-selection-access/cmd1
-rw-r--r--test/regression/0-crash-on-pipe-with-selection-access/in3
-rw-r--r--test/regression/0-crash-on-pipe-with-selection-access/out1
4 files changed, 14 insertions, 3 deletions
diff --git a/src/normal.cc b/src/normal.cc
index 363ebc8a..483be93c 100644
--- a/src/normal.cc
+++ b/src/normal.cc
@@ -512,9 +512,11 @@ void pipe(Context& context, NormalParams)
return;
Buffer& buffer = context.buffer();
- SelectionList& selections = context.selections();
- const int old_main = selections.main_index();
- auto restore_main = on_scope_end([&] { selections.set_main_index(old_main); });
+ SelectionList selections = context.selections();
+ auto restore_sels = on_scope_end([&, old_main = selections.main_index()] {
+ selections.set_main_index(old_main);
+ context.selections() = std::move(selections);
+ });
if (replace)
{
ScopedEdition edition(context);
@@ -531,6 +533,10 @@ void pipe(Context& context, NormalParams)
const bool insert_eol = in.back() != '\n';
if (insert_eol)
in += '\n';
+
+ // Needed in case we read selections inside the cmdline
+ context.selections_write_only() = selections;
+
String out = ShellManager::instance().eval(
cmdline, context, in,
ShellManager::Flags::WaitForStdout).first;
diff --git a/test/regression/0-crash-on-pipe-with-selection-access/cmd b/test/regression/0-crash-on-pipe-with-selection-access/cmd
new file mode 100644
index 00000000..be5c4524
--- /dev/null
+++ b/test/regression/0-crash-on-pipe-with-selection-access/cmd
@@ -0,0 +1 @@
+%<a-s>|[ $kak_selection = "bar" ] && echo "yes"<ret>
diff --git a/test/regression/0-crash-on-pipe-with-selection-access/in b/test/regression/0-crash-on-pipe-with-selection-access/in
new file mode 100644
index 00000000..86e041da
--- /dev/null
+++ b/test/regression/0-crash-on-pipe-with-selection-access/in
@@ -0,0 +1,3 @@
+foo
+bar
+baz
diff --git a/test/regression/0-crash-on-pipe-with-selection-access/out b/test/regression/0-crash-on-pipe-with-selection-access/out
new file mode 100644
index 00000000..7cfab5b0
--- /dev/null
+++ b/test/regression/0-crash-on-pipe-with-selection-access/out
@@ -0,0 +1 @@
+yes