From 4e4852c40ab5cf5979d5b484d7d2809093704891 Mon Sep 17 00:00:00 2001 From: Fabian Homborg Date: Sun, 28 Mar 2021 20:20:17 +0200 Subject: [PATCH] history: Improve bash import check - Check for special characters *before* attempting to parse - Also ignore lines with `{` and `*` - Also skip lines with `<<` because that might be a heredoc (or a - `<<<` herestring) Fixes #7874. --- src/fish_tests.cpp | 2 +- src/history.cpp | 29 +++++++++++++++-------------- tests/history_sample_bash | 3 +++ 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/fish_tests.cpp b/src/fish_tests.cpp index 9d7ffd092..52aa2e6c4 100644 --- a/src/fish_tests.cpp +++ b/src/fish_tests.cpp @@ -4640,7 +4640,7 @@ void history_tests_t::test_history_formats() { // The results are in the reverse order that they appear in the bash history file. // We don't expect whitespace to be elided (#4908: except for leading/trailing whitespace) const wchar_t *expected[] = { - L"/** # see issue 7407", L"sleep 123", L"a && echo valid construct", + L"EOF", L"sleep 123", L"a && echo valid construct", L"final line", L"echo supsup", L"export XVAR='exported'", L"history --help", L"echo foo", NULL}; auto test_history = history_t::with_name(L"bash_import"); diff --git a/src/history.cpp b/src/history.cpp index 4890c345e..71210e6d9 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -1139,32 +1139,33 @@ void history_impl_t::populate_from_config_path() { static bool should_import_bash_history_line(const wcstring &line) { if (line.empty()) return false; - if (ast::ast_t::parse(line).errored()) return false; - - // In doing this test do not allow incomplete strings. Hence the "false" argument. - parse_error_list_t errors; - parse_util_detect_errors(line, &errors); - if (!errors.empty()) return false; - // The following are Very naive tests! // Skip comments. if (line[0] == '#') return false; - // Skip lines with backticks. - if (line.find('`') != std::string::npos) return false; + // Skip lines with backticks because we don't have that syntax, + // Skip brace expansions and globs because they don't work like ours + // Skip lines with literal tabs since we don't handle them well and we don't know what they + // mean. It could just be whitespace or it's actually passed somewhere (like e.g. `sed`). + // Skip lines that end with a backslash. We do not handle multiline commands from bash history. + if (line.find_first_of(L"`{*\t\\") != std::string::npos) return false; // Skip lines with [[...]] and ((...)) since we don't handle those constructs. if (line.find(L"[[") != std::string::npos) return false; if (line.find(L"]]") != std::string::npos) return false; if (line.find(L"((") != std::string::npos) return false; if (line.find(L"))") != std::string::npos) return false; - // Skip lines with literal tabs since we don't handle them well and we don't know what they - // mean. It could just be whitespace or it's actually passed somewhere (like e.g. `sed`). - if (line.find(L'\t') != std::string::npos) return false; + // "<<" here is a proxy for heredocs (and herestrings). + if (line.find(L"<<") != std::string::npos) return false; - // Skip lines that end with a backslash. We do not handle multiline commands from bash history. - if (line.back() == L'\\') return false; + + if (ast::ast_t::parse(line).errored()) return false; + + // In doing this test do not allow incomplete strings. Hence the "false" argument. + parse_error_list_t errors; + parse_util_detect_errors(line, &errors); + if (!errors.empty()) return false; return true; } diff --git a/tests/history_sample_bash b/tests/history_sample_bash index 1f3fd73c9..3094c9a39 100644 --- a/tests/history_sample_bash +++ b/tests/history_sample_bash @@ -18,3 +18,6 @@ a && echo valid construct posix_cmd_sub $(is not supported) sleep 123 /** # see issue 7407 +jq <<"EOF" +[{"background":null,"color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3c3836","full_text":"  141.57 GiB ","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3C3836FF","full_text":" ","markup":"pango","name":"e49dcba19c99470ca906c84bd7e2d26c","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3c3836","full_text":"  ","markup":"pango","name":"628b16c2ef8947d2aaab8e976c3eb135","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3C3836FF","full_text":"  5.3/15.5 (34%) ","markup":"pango","name":"memory","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3c3836","full_text":" compositor is already running ","markup":"pango","name":"e4033a10be4a4b05abd714430d0d7441","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#FBF1C7FF","full_text":"  ","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3c3836","full_text":"  43° ","markup":"pango","name":"832500be70604dc485e351d1e552cec6","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3C3836FF","full_text":"  4d 3h ","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3c3836","full_text":"  n/a ","markup":"pango","name":"b3d7736948aa4c22a9392ec46715f160","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#00000000","full_text":"","markup":"pango","separator":false,"separator_block_width":0},{"background":"#00000000","color":"#3C3836FF","full_text":" Monday 2019-07-15 10:51 pm ","markup":"pango","name":"7ac94d496c354d7d82734fb7bd9d6e3d","separator":false,"separator_block_width":0}] +EOF