mirror of
https://github.com/NixOS/nix.git
synced 2025-11-27 12:41:00 +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
|
|
@ -89,6 +89,9 @@ StringMap EvalState::realiseContext(const NixStringContext & context, StorePathS
|
|||
if (maybePathsOut)
|
||||
maybePathsOut->emplace(d.drvPath);
|
||||
},
|
||||
[&](const NixStringContextElem::Path & p) {
|
||||
// FIXME
|
||||
},
|
||||
}, c.raw);
|
||||
}
|
||||
|
||||
|
|
@ -1438,6 +1441,9 @@ static void derivationStrictInternal(
|
|||
[&](const NixStringContextElem::Opaque & o) {
|
||||
drv.inputSrcs.insert(state.devirtualize(o.path, &rewrites));
|
||||
},
|
||||
[&](const NixStringContextElem::Path & p) {
|
||||
// FIXME: do something
|
||||
},
|
||||
}, c.raw);
|
||||
}
|
||||
|
||||
|
|
@ -2346,10 +2352,21 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val
|
|||
std::string contents(state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.toFile"));
|
||||
|
||||
StorePathSet refs;
|
||||
StringMap rewrites;
|
||||
|
||||
for (auto c : context) {
|
||||
if (auto p = std::get_if<NixStringContextElem::Opaque>(&c.raw))
|
||||
refs.insert(p->path);
|
||||
else if (auto p = std::get_if<NixStringContextElem::Path>(&c.raw)) {
|
||||
if (contents.find(p->storePath.to_string()) != contents.npos) {
|
||||
warn(
|
||||
"Using 'builtins.toFile' to create a file named '%s' that references the store path '%s' without a proper context. "
|
||||
"The resulting file will not have a correct store reference, so this is unreliable and may stop working in the future.",
|
||||
name,
|
||||
state.store->printStorePath(p->storePath));
|
||||
state.devirtualize(p->storePath, &rewrites);
|
||||
}
|
||||
}
|
||||
else
|
||||
state.error<EvalError>(
|
||||
"files created by %1% may not reference derivations, but %2% references %3%",
|
||||
|
|
@ -2359,6 +2376,8 @@ static void prim_toFile(EvalState & state, const PosIdx pos, Value * * args, Val
|
|||
).atPos(pos).debugThrow();
|
||||
}
|
||||
|
||||
contents = rewriteStrings(contents, rewrites);
|
||||
|
||||
auto storePath = settings.readOnlyMode
|
||||
? state.store->makeFixedOutputPathFromCA(name, TextInfo {
|
||||
.hash = hashString(HashAlgorithm::SHA256, contents),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue