From 04993de68765d64e6da882e4fd055fdc07bd736b Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 7 Nov 2017 23:58:56 +0800 Subject: [PATCH] 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. --- src/normal.cc | 12 +++++++++--- .../0-crash-on-pipe-with-selection-access/cmd | 1 + .../0-crash-on-pipe-with-selection-access/in | 3 +++ .../0-crash-on-pipe-with-selection-access/out | 1 + 4 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 test/regression/0-crash-on-pipe-with-selection-access/cmd create mode 100644 test/regression/0-crash-on-pipe-with-selection-access/in create mode 100644 test/regression/0-crash-on-pipe-with-selection-access/out 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 @@ +%|[ $kak_selection = "bar" ] && echo "yes" 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