1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-28 13:41:15 +02:00

fix: segfault in positional arg completion

Adding the inputPath as a positional feature uncovered this bug.
As positional argument forms were discarded from the `expectedArgs`
list, their closures were not. When the `.completer` closure was then
called, part of the surrounding object did not exist anymore.

This didn't cause an issue before, but with the new call to
`getEvalState()` in the "inputs" completer in nix/flake.cc, a segfault
was triggered reproducibly on invalid memory access to the `this`
pointer, which was always 0.

The solution of splicing the argument forms into a new list to extend
their lifetime is a bit of a hack, but I was unable to get the "nicer"
iterator-based solution to work.
This commit is contained in:
Felix Uhl 2023-10-24 22:22:05 +02:00 committed by Théophane Hufschmitt
parent c7dcdb8325
commit f282ef5a56
3 changed files with 29 additions and 2 deletions

View file

@ -255,7 +255,18 @@ bool Args::processArgs(const Strings & args, bool finish)
}
if (!anyCompleted)
exp.handler.fun(ss);
expectedArgs.pop_front();
/* Move the list element to the processedArgs. This is almost the same as
`processedArgs.push_back(expectedArgs.front()); expectedArgs.pop_front()`,
except that it will only adjust the next and prev pointers of the list
elements, meaning the actual contents don't move in memory. This is
critical to prevent invalidating internal pointers! */
processedArgs.splice(
processedArgs.end(),
expectedArgs,
expectedArgs.begin(),
++expectedArgs.begin());
res = true;
}