From 5d17e1132fa0a7c528223e76e179133006198c9e Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Tue, 22 Sep 2020 21:14:40 +1000 Subject: [PATCH] Ensure that the capture group actually matched in select_matches We were creating selections from default constructed iterators, which happened to have 0,0 coords and led to out-of-order selection lists. Fixes #3757 --- src/selectors.cc | 20 ++++++++++--------- src/selectors.hh | 4 ++-- .../3757-crash-on-capture-group-select/cmd | 1 + .../3757-crash-on-capture-group-select/in | 2 ++ .../3757-crash-on-capture-group-select/out | 2 ++ 5 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 test/regression/3757-crash-on-capture-group-select/cmd create mode 100644 test/regression/3757-crash-on-capture-group-select/in create mode 100644 test/regression/3757-crash-on-capture-group-select/out diff --git a/src/selectors.cc b/src/selectors.cc index a77a2379..b0aa83b0 100644 --- a/src/selectors.cc +++ b/src/selectors.cc @@ -929,10 +929,10 @@ Selection find_next_match(const Context& context, const Selection& sel, const Re template Selection find_next_match(const Context&, const Selection&, const Regex&, bool&); template Selection find_next_match(const Context&, const Selection&, const Regex&, bool&); -Vector select_matches(const Buffer& buffer, ConstArrayView selections, const Regex& regex, int capture) +Vector select_matches(const Buffer& buffer, ConstArrayView selections, const Regex& regex, int capture_idx) { const int mark_count = (int)regex.mark_count(); - if (capture < 0 or capture > mark_count) + if (capture_idx < 0 or capture_idx > mark_count) throw runtime_error("invalid capture number"); Vector result; @@ -944,10 +944,9 @@ Vector select_matches(const Buffer& buffer, ConstArrayView for (auto&& match : RegexIterator{sel_beg, sel_end, vm, match_flags(buffer, sel_beg, sel_end)}) { - auto begin = match[capture].first; - if (begin == sel_end) + auto capture = match[capture_idx]; + if (not capture.matched or capture.first == sel_end) continue; - auto end = match[capture].second; CaptureList captures; captures.reserve(mark_count); @@ -955,6 +954,8 @@ Vector select_matches(const Buffer& buffer, ConstArrayView captures.push_back(buffer.string(submatch.first.coord(), submatch.second.coord())); + auto begin = capture.first, end = capture.second; + kak_assert(result.empty() or begin.coord() >= result.back().min()); result.push_back( keep_direction({ begin.coord(), (begin == end ? end : utf8::previous(end, begin)).coord(), @@ -966,9 +967,9 @@ Vector select_matches(const Buffer& buffer, ConstArrayView return result; } -Vector split_on_matches(const Buffer& buffer, ConstArrayView selections, const Regex& regex, int capture) +Vector split_on_matches(const Buffer& buffer, ConstArrayView selections, const Regex& regex, int capture_idx) { - if (capture < 0 or capture > (int)regex.mark_count()) + if (capture_idx < 0 or capture_idx > (int)regex.mark_count()) throw runtime_error("invalid capture number"); Vector result; @@ -982,7 +983,8 @@ Vector split_on_matches(const Buffer& buffer, ConstArrayView split_on_matches(const Buffer& buffer, ConstArrayView select_matches(const Buffer& buffer, ConstArrayView selections, - const Regex& regex, int capture = 0); + const Regex& regex, int capture_idx = 0); Vector split_on_matches(const Buffer& buffer, ConstArrayView selections, - const Regex& regex, int capture = 0); + const Regex& regex, int capture_idx = 0); Optional select_surrounding(const Context& context, const Selection& selection, diff --git a/test/regression/3757-crash-on-capture-group-select/cmd b/test/regression/3757-crash-on-capture-group-select/cmd new file mode 100644 index 00000000..b1739311 --- /dev/null +++ b/test/regression/3757-crash-on-capture-group-select/cmd @@ -0,0 +1 @@ +%1sfoo(.*)| diff --git a/test/regression/3757-crash-on-capture-group-select/in b/test/regression/3757-crash-on-capture-group-select/in new file mode 100644 index 00000000..3bd1f0e2 --- /dev/null +++ b/test/regression/3757-crash-on-capture-group-select/in @@ -0,0 +1,2 @@ +foo +bar diff --git a/test/regression/3757-crash-on-capture-group-select/out b/test/regression/3757-crash-on-capture-group-select/out new file mode 100644 index 00000000..3bd1f0e2 --- /dev/null +++ b/test/regression/3757-crash-on-capture-group-select/out @@ -0,0 +1,2 @@ +foo +bar