From 20d50b049d48eb2e762452112e64c47c9dfe21ec Mon Sep 17 00:00:00 2001 From: "git@71rd.net" Date: Mon, 26 May 2025 16:54:50 +0000 Subject: [PATCH] libutil/args: dont crash completion when receiving incorrect number of arguments When using completion, the number of the word for which the shell requests completion is provided in the environment variable `NIX_GET_COMPLETIONS`. When the number smaller than 1 is or larger than the number of arguments nix coredumps as a assert is violated. This change removes the assert and instead throws an exception informing the user that their autocomplete is most likely misconfigured. Change-Id: I821719e470e576b6f63c06beb097338b53d183e0 --- lix/libutil/args.cc | 3 ++- tests/functional/completions.sh | 6 ++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/lix/libutil/args.cc b/lix/libutil/args.cc index d8a88f003..bcd142607 100644 --- a/lix/libutil/args.cc +++ b/lix/libutil/args.cc @@ -87,7 +87,8 @@ void RootArgs::parseCmdline(const Strings & _cmdline) if (auto s = getEnv("NIX_GET_COMPLETIONS")) { size_t n = std::stoi(*s); - assert(n > 0 && n <= cmdline.size()); + if (!(n > 0 && n <= cmdline.size())) + throw UsageError("Invalid word number to get completion for: %zu\n. Your autocompletions might be misconfigured", n); *std::next(cmdline.begin(), n - 1) += completionMarker; completions = std::make_shared(); verbosity = lvlError; diff --git a/tests/functional/completions.sh b/tests/functional/completions.sh index d3d5bbd48..610c15529 100644 --- a/tests/functional/completions.sh +++ b/tests/functional/completions.sh @@ -37,6 +37,12 @@ EOF [[ "$(NIX_GET_COMPLETIONS=1 nix buil)" == $'normal\nbuild\t' ]] [[ "$(NIX_GET_COMPLETIONS=2 nix flake metad)" == $'normal\nmetadata\t' ]] +# Test how completion fails if the number is not a valid index for the number of arguments +NIX_GET_COMPLETIONS=0 expectStderr 1 nix \ + | grepQuiet "error: Invalid word number to get completion for:" +NIX_GET_COMPLETIONS=4 expectStderr 1 nix build a \ + | grepQuiet "error: Invalid word number to get completion for:" + # Filename completion [[ "$(NIX_GET_COMPLETIONS=2 nix build ./f)" == $'filenames\n./foo\t' ]] [[ "$(NIX_GET_COMPLETIONS=2 nix build ./nonexistent)" == $'filenames' ]]