From 0e115a4828706e6c3551eacf6d78fac603f0f13f Mon Sep 17 00:00:00 2001 From: "git@71rd.net" Date: Tue, 27 May 2025 15:14:58 +0000 Subject: [PATCH] libutil/args: fix crash when NIX_GET_COMPLETIONS is not a number When assigning an a value to NIX_GET_COMPLETIONS that could not be parsed as an integer lix would just crash, as the value was directly passed to stoi, without handling the return value. This change switches the parsing to use string2Int and throws an exception if the return value is empty. The behaviour of lix is slightly changed through, as the value of the variable was previously parsed to an int and then assigned to a variable of size_t. This change in behaviour can only be observed in cases where the value of NIX_GET_COMPLETIONS is chosen so when it overflows it would be valid index of the provided arguments again. Through this change the variable is parsed as a size_t and negative values are rejected. Change-Id: Idf7c5740274c6e07d5bb13d7e2ed32764bfc27f8 --- lix/libutil/args.cc | 8 +++++++- tests/functional/completions.sh | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/lix/libutil/args.cc b/lix/libutil/args.cc index bcd142607..9a75b99ee 100644 --- a/lix/libutil/args.cc +++ b/lix/libutil/args.cc @@ -86,7 +86,13 @@ void RootArgs::parseCmdline(const Strings & _cmdline) Strings cmdline(_cmdline); if (auto s = getEnv("NIX_GET_COMPLETIONS")) { - size_t n = std::stoi(*s); + size_t n = [&] { + if (auto parsed = string2Int(*s)) { + return *parsed; + } + throw UsageError("Invalid value for environment variable NIX_GET_COMPLETIONS: %s", *s); + }(); + 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; diff --git a/tests/functional/completions.sh b/tests/functional/completions.sh index 610c15529..378bd1c15 100644 --- a/tests/functional/completions.sh +++ b/tests/functional/completions.sh @@ -37,6 +37,11 @@ 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 value cant be parsed as a number +NIX_GET_COMPLETIONS="-" expectStderr 1 nix \ + | grepQuiet "error: Invalid value for environment variable NIX_GET_COMPLETIONS:" + # 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:"