mirror of
https://github.com/NixOS/nix.git
synced 2025-12-10 11:01:03 +01:00
Add a special type of context for the result of toString
When you apply `builtins.toString` to a path value representing a path in the Nix store (as is the case with flake inputs), historically you got a string without context (e.g. `/nix/store/...-source`). This is broken, since it allows you to pass a store path to a derivation/toFile without a proper store reference. This is especially a problem with lazy trees, since the store path is a virtual path that doesn't exist and can be different every time. For backwards compatibility, and to warn users about this unsafe use of `toString`, we now keep track of such strings as a special type of context.
This commit is contained in:
parent
8c568277fd
commit
2a35d8f800
10 changed files with 129 additions and 10 deletions
|
|
@ -952,8 +952,8 @@ void EvalState::mkPos(Value & v, PosIdx p)
|
|||
// FIXME: only do this for virtual store paths?
|
||||
attrs.alloc(sFile).mkString(path->path.abs(),
|
||||
{
|
||||
NixStringContextElem::Opaque{
|
||||
.path = store->toStorePath(path->path.abs()).first
|
||||
NixStringContextElem::Path{
|
||||
.storePath = store->toStorePath(path->path.abs()).first
|
||||
}
|
||||
});
|
||||
else
|
||||
|
|
@ -2277,7 +2277,10 @@ std::string_view EvalState::forceStringNoCtx(Value & v, const PosIdx pos, std::s
|
|||
{
|
||||
auto s = forceString(v, pos, errorCtx);
|
||||
if (v.context()) {
|
||||
error<EvalError>("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string_view(), v.context()[0]).withTrace(pos, errorCtx).debugThrow();
|
||||
NixStringContext context;
|
||||
copyContext(v, context);
|
||||
if (hasContext(context))
|
||||
error<EvalError>("the string '%1%' is not allowed to refer to a store path (such as '%2%')", v.string_view(), v.context()[0]).withTrace(pos, errorCtx).debugThrow();
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
|
@ -2336,7 +2339,16 @@ BackedStringView EvalState::coerceToString(
|
|||
v.payload.path.path
|
||||
: copyToStore
|
||||
? store->printStorePath(copyPathToStore(context, v.path()))
|
||||
: std::string(v.path().path.abs());
|
||||
: ({
|
||||
auto path = v.path();
|
||||
if (path.accessor == rootFS && store->isInStore(path.path.abs())) {
|
||||
context.insert(
|
||||
NixStringContextElem::Path{
|
||||
.storePath = store->toStorePath(path.path.abs()).first
|
||||
});
|
||||
}
|
||||
std::string(path.path.abs());
|
||||
});
|
||||
}
|
||||
|
||||
if (v.type() == nAttrs) {
|
||||
|
|
@ -2499,6 +2511,9 @@ std::pair<SingleDerivedPath, std::string_view> EvalState::coerceToSingleDerivedP
|
|||
[&](NixStringContextElem::Built && b) -> SingleDerivedPath {
|
||||
return std::move(b);
|
||||
},
|
||||
[&](NixStringContextElem::Path && p) -> SingleDerivedPath {
|
||||
abort(); // FIXME
|
||||
},
|
||||
}, ((NixStringContextElem &&) *context.begin()).raw);
|
||||
return {
|
||||
std::move(derivedPath),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue