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.
This commit is contained in:
tomKPZ 2022-03-08 08:51:11 -08:00
parent 82db91c58c
commit f709ba6390

View File

@ -132,7 +132,7 @@ ParseResult parse_quoted(ParseState& state, Delimiter delimiter)
if (c == delimiter) if (c == delimiter)
{ {
auto next = state.pos; auto next = state.pos;
if (read(next, end) != delimiter) if (next == end || read(next, end) != delimiter)
{ {
if (str.empty()) if (str.empty())
return {String{String::NoCopy{}, {beg, cur}}, true}; return {String{String::NoCopy{}, {beg, cur}}, true};
@ -815,15 +815,20 @@ UnitTest test_command_parsing{[]
{ {
auto check_quoted = [](StringView str, bool terminated, StringView content) auto check_quoted = [](StringView str, bool terminated, StringView content)
{ {
auto check_quoted_impl = [&](auto type_hint) {
ParseState state{str, str.begin()}; ParseState state{str, str.begin()};
const Codepoint delimiter = *state.pos++; const decltype(type_hint) delimiter = *state.pos++;
auto quoted = parse_quoted(state, delimiter); auto quoted = parse_quoted(state, delimiter);
kak_assert(quoted.terminated == terminated); kak_assert(quoted.terminated == terminated);
kak_assert(quoted.content == content); kak_assert(quoted.content == content);
}; };
check_quoted_impl(Codepoint{});
check_quoted_impl(char{});
};
check_quoted("'abc'", true, "abc"); check_quoted("'abc'", true, "abc");
check_quoted("'abc''def", false, "abc'def"); check_quoted("'abc''def", false, "abc'def");
check_quoted("'abc''def'''", true, "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) auto check_balanced = [](StringView str, bool terminated, StringView content)
{ {