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:
parent
c7dcdb8325
commit
f282ef5a56
3 changed files with 29 additions and 2 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue