diff options
| author | Maxime Coste <mawww@kakoune.org> | 2018-05-07 07:29:52 +1000 |
|---|---|---|
| committer | Maxime Coste <mawww@kakoune.org> | 2018-07-05 07:54:28 +1000 |
| commit | ec1696960982464ead78efcaa0406c71d8acc12d (patch) | |
| tree | edca1ef620e4472697971b30e71d5ff343c96759 /src/command_manager.cc | |
| parent | 3b9818c10b6f3c6fd19aa90115c4c3e14dc2d236 (diff) | |
Do not reparse %sh{...} strings
Automatic reparsing of %sh{...}, while convenient in many cases,
can be surprising as well, and can lead to security problems:
'echo %sh{ printf "foo\necho bar" }' runs 'echo foo', then 'echo bar'.
we make this danger explicit, and we fix the 'nop %sh{...}' pattern.
To reparse %sh{...} strings, they can be passed to evaluate-commands,
which has been fixed to work in every cases where %sh{...} reparsing
was used..
Diffstat (limited to 'src/command_manager.cc')
| -rw-r--r-- | src/command_manager.cc | 24 |
1 files changed, 3 insertions, 21 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc index 94182f4d..9429b334 100644 --- a/src/command_manager.cc +++ b/src/command_manager.cc @@ -171,6 +171,7 @@ Token parse_percent_token(Reader& reader, bool throw_on_unterminated) { kak_assert(*reader == '%'); ++reader; + const auto type_start = reader.pos; while (reader and iswalpha(*reader)) ++reader; @@ -441,26 +442,10 @@ void CommandManager::execute(StringView command_line, Context& context, const ShellContext& shell_context) { CommandParser parser(command_line); - struct ShellParser { - ShellParser(String&& str) : output{std::move(str)}, parser{output} {} - String output; - CommandParser parser; - }; - Vector<ShellParser> shell_parser_stack; - - auto next_token = [&] { - while (not shell_parser_stack.empty()) - { - if (auto shell_token = shell_parser_stack.back().parser.read_token(true)) - return shell_token; - shell_parser_stack.pop_back(); - } - return parser.read_token(true); - }; BufferCoord command_coord; - Vector<String> params; - while (Optional<Token> token_opt = next_token()) + Vector<String, MemoryDomain::Commands> params; + while (Optional<Token> token_opt = parser.read_token(true)) { auto& token = *token_opt; if (params.empty()) @@ -471,9 +456,6 @@ void CommandManager::execute(StringView command_line, execute_single_command(params, context, shell_context, command_coord); params.clear(); } - // Shell expand are retokenized - else if (token.type == Token::Type::ShellExpand) - shell_parser_stack.emplace_back(expand_token(token, context, shell_context)); else if (token.type == Token::Type::ArgExpand and token.content == '@') params.insert(params.end(), shell_context.params.begin(), shell_context.params.end()); |
