From c94dec5d0ec0987938fb5d2b6181e856e4cba746 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Sun, 31 Oct 2021 13:44:38 +0100 Subject: [PATCH] Fix assertion error trying to highlight cmdsubs inside unbalanced quotes I initially put this logic + assertion in another function, where we always get balanced quotes. Not for highlighting. --- src/fish_tests.cpp | 8 ++++++++ src/parse_util.cpp | 13 ++++++++++--- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 931c56cfc..e1b213bff 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -5296,6 +5296,14 @@ static void test_highlighting() { {L"after\"", highlight_role_t::quote}, {L"param2", highlight_role_t::param}, }); + highlight_tests.push_back({ + {L"true", highlight_role_t::command}, + {L"\"", highlight_role_t::error}, + {L"unclosed quote", highlight_role_t::quote}, + {L"$(", highlight_role_t::operat}, + {L"true", highlight_role_t::command}, + {L")", highlight_role_t::operat}, + }); // Redirections substitutions. highlight_tests.push_back({ diff --git a/src/parse_util.cpp b/src/parse_util.cpp index 595fe621d..be9d30843 100644 --- a/src/parse_util.cpp +++ b/src/parse_util.cpp @@ -275,9 +275,16 @@ int parse_util_locate_cmdsubst_range(const wcstring &str, size_t *inout_cursor_o // quoted but the naïve next caller wouldn't know. Since next caller only cares about // the next command substitution - (C) - and not about the B part, just advance the // cursor to the closing quote. - const wchar_t *q_end = quote_end(bracket_range_end, L'"'); - assert(q_end && "expect balanced quotes"); - *inout_cursor_offset = 1 + q_end - buff; + if (auto *q_end = quote_end(bracket_range_end, L'"')) { + *inout_cursor_offset = 1 + q_end - buff; + } else { + if (accept_incomplete) { + // We want to skip quoted text, so if there is no closing quote, skip to the end. + *inout_cursor_offset = bracket_range_end + std::wcslen(bracket_range_end) - buff; + } else { + return -1; + } + } } return ret;