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
This commit is contained in:
git@71rd.net
2025-05-27 22:20:22 +00:00
parent 20d50b049d
commit 0e115a4828
2 changed files with 12 additions and 1 deletions
+7 -1
View File
@@ -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<size_t>(*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;
+5
View File
@@ -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:"