diff --git a/src/reader.cpp b/src/reader.cpp index 20aeb3348..3b743b19e 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -2561,6 +2561,11 @@ void reader_data_t::handle_readline_command(readline_cmd_t c, readline_loop_stat completion_request_t::fuzzy_match}; complete_func(buffcpy, &rls.comp, complete_flags, vars, parser_ref); + + // User-supplied completions may have changed the commandline - prevent buffer overflow. + if (token_begin > buff + el->text.size()) token_begin = buff + el->text.size(); + if (token_end > buff + el->text.size()) token_end = buff + el->text.size(); + // Munge our completions. completions_sort_and_prioritize(&rls.comp); diff --git a/tests/complete.expect b/tests/complete.expect new file mode 100644 index 000000000..0d929ae8c --- /dev/null +++ b/tests/complete.expect @@ -0,0 +1,20 @@ +# vim: set filetype=expect: +spawn $fish +set sid $spawn_id +expect_prompt + +send_line { + complete -c my_is -n 'test (count (commandline -opc)) = 1' -xa arg + complete -c my_is -n '__fish_seen_subcommand_from not' -xa '( + set -l cmd (commandline -opc) (commandline -ct) + set cmd (string join " " my_is $cmd[3..-1])" " + commandline --replace --current-process $cmd + complete -C"$cmd" + )' +} +send "my_is not \t" +send "still.alive" +expect -re {.*still.alive} { +} eof { + error "did fish crash?" +} diff --git a/tests/complete.expect.err b/tests/complete.expect.err new file mode 100644 index 000000000..e69de29bb diff --git a/tests/complete.expect.out b/tests/complete.expect.out new file mode 100644 index 000000000..e69de29bb