From f709ba63907bb6aa7bf256c1d1fce83e17d5f0ff Mon Sep 17 00:00:00 2001 From: tomKPZ Date: Tue, 8 Mar 2022 08:51:11 -0800 Subject: [PATCH] Fix buffer overflow in parse_quoted This fixes a crash when using kak-lsp with bash-language-server. The issue is that the second read() in parse_quoted may read past the end of the string. If this happens and the condition on line 126 is false, then the loop on line 119 will continue to read past the end of the buffer since it checks for state.pos != end instead of state.pos < end, which will likely result in a crash. The fix is to add a check for the buffer end before the second read. The added test fails without the change and passes with the change. --- src/command_manager.cc | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/command_manager.cc b/src/command_manager.cc index 0f3cb749..b8784093 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -132,7 +132,7 @@ ParseResult parse_quoted(ParseState& state, Delimiter delimiter) if (c == delimiter) { auto next = state.pos; - if (read(next, end) != delimiter) + if (next == end || read(next, end) != delimiter) { if (str.empty()) return {String{String::NoCopy{}, {beg, cur}}, true}; @@ -815,15 +815,20 @@ UnitTest test_command_parsing{[] { auto check_quoted = [](StringView str, bool terminated, StringView content) { - ParseState state{str, str.begin()}; - const Codepoint delimiter = *state.pos++; - auto quoted = parse_quoted(state, delimiter); - kak_assert(quoted.terminated == terminated); - kak_assert(quoted.content == content); + auto check_quoted_impl = [&](auto type_hint) { + ParseState state{str, str.begin()}; + const decltype(type_hint) delimiter = *state.pos++; + auto quoted = parse_quoted(state, delimiter); + kak_assert(quoted.terminated == terminated); + kak_assert(quoted.content == content); + }; + check_quoted_impl(Codepoint{}); + check_quoted_impl(char{}); }; check_quoted("'abc'", true, "abc"); check_quoted("'abc''def", false, "abc'def"); check_quoted("'abc''def'''", true, "abc'def'"); + check_quoted(StringView("'abc''def'", 5), true, "abc"); auto check_balanced = [](StringView str, bool terminated, StringView content) {