mirror of
https://github.com/NixOS/nix
synced 2025-07-05 16:31:47 +02:00
fix: Handle symlinks and FIFOs in nix hash
where possible
Fixes https://github.com/NixOS/nix/issues/11756
Fixes https://github.com/NixOS/nix/issues/11681
(cherry picked from commit 36563c69a4
)
This commit is contained in:
parent
fa3fd41063
commit
b9c30a9c87
3 changed files with 45 additions and 4 deletions
|
@ -43,7 +43,7 @@ struct PosixSourceAccessor : virtual SourceAccessor
|
|||
std::optional<std::filesystem::path> getPhysicalPath(const CanonPath & path) override;
|
||||
|
||||
/**
|
||||
* Create a `PosixSourceAccessor` and `CanonPath` corresponding to
|
||||
* Create a `PosixSourceAccessor` and `SourcePath` corresponding to
|
||||
* some native path.
|
||||
*
|
||||
* The `PosixSourceAccessor` is rooted as far up the tree as
|
||||
|
|
|
@ -87,18 +87,35 @@ struct CmdHashBase : Command
|
|||
return std::make_unique<HashSink>(hashAlgo);
|
||||
};
|
||||
|
||||
auto path2 = PosixSourceAccessor::createAtRoot(path);
|
||||
auto makeSourcePath = [&]() -> SourcePath {
|
||||
return PosixSourceAccessor::createAtRoot(makeParentCanonical(path));
|
||||
};
|
||||
|
||||
Hash h { HashAlgorithm::SHA256 }; // throwaway def to appease C++
|
||||
switch (mode) {
|
||||
case FileIngestionMethod::Flat:
|
||||
{
|
||||
// While usually we could use the some code as for NixArchive,
|
||||
// the Flat method needs to support FIFOs, such as those
|
||||
// produced by bash process substitution, e.g.:
|
||||
// nix hash --mode flat <(echo hi)
|
||||
// Also symlinks semantics are unambiguous in the flat case,
|
||||
// so we don't need to go low-level, or reject symlink `path`s.
|
||||
auto hashSink = makeSink();
|
||||
readFile(path, *hashSink);
|
||||
h = hashSink->finish().first;
|
||||
break;
|
||||
}
|
||||
case FileIngestionMethod::NixArchive:
|
||||
{
|
||||
auto sourcePath = makeSourcePath();
|
||||
auto hashSink = makeSink();
|
||||
dumpPath(path2, *hashSink, (FileSerialisationMethod) mode);
|
||||
dumpPath(sourcePath, *hashSink, (FileSerialisationMethod) mode);
|
||||
h = hashSink->finish().first;
|
||||
break;
|
||||
}
|
||||
case FileIngestionMethod::Git: {
|
||||
auto sourcePath = makeSourcePath();
|
||||
std::function<git::DumpHook> hook;
|
||||
hook = [&](const SourcePath & path) -> git::TreeEntry {
|
||||
auto hashSink = makeSink();
|
||||
|
@ -109,7 +126,7 @@ struct CmdHashBase : Command
|
|||
.hash = hash,
|
||||
};
|
||||
};
|
||||
h = hook(path2).hash;
|
||||
h = hook(sourcePath).hash;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue