mirror of
https://github.com/NixOS/nix
synced 2025-07-05 12:21:48 +02:00
Merge commit from fork
Fix unsafe NAR unpacking
This commit is contained in:
commit
9c0e968843
9 changed files with 113 additions and 37 deletions
|
@ -23,7 +23,7 @@ struct ArchiveSettings : Config
|
|||
false,
|
||||
#endif
|
||||
"use-case-hack",
|
||||
"Whether to enable a Darwin-specific hack for dealing with file name collisions."};
|
||||
"Whether to enable a macOS-specific hack for dealing with file name case collisions."};
|
||||
};
|
||||
|
||||
static ArchiveSettings archiveSettings;
|
||||
|
@ -214,11 +214,13 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath
|
|||
else if (t == "directory") {
|
||||
sink.createDirectory(path);
|
||||
|
||||
std::string prevName;
|
||||
|
||||
while (1) {
|
||||
s = getString();
|
||||
|
||||
if (s == "entry") {
|
||||
std::string name, prevName;
|
||||
std::string name;
|
||||
|
||||
s = getString();
|
||||
if (s != "(") throw badArchive("expected open tag");
|
||||
|
@ -241,6 +243,9 @@ static void parse(FileSystemObjectSink & sink, Source & source, const CanonPath
|
|||
debug("case collision between '%1%' and '%2%'", i->first, name);
|
||||
name += caseHackSuffix;
|
||||
name += std::to_string(++i->second);
|
||||
auto j = names.find(name);
|
||||
if (j != names.end())
|
||||
throw Error("NAR contains file name '%s' that collides with case-hacked file name '%s'", prevName, j->first);
|
||||
} else
|
||||
names[name] = 0;
|
||||
}
|
||||
|
|
|
@ -68,10 +68,19 @@ static RestoreSinkSettings restoreSinkSettings;
|
|||
|
||||
static GlobalConfig::Register r1(&restoreSinkSettings);
|
||||
|
||||
static std::filesystem::path append(const std::filesystem::path & src, const CanonPath & path)
|
||||
{
|
||||
auto dst = src;
|
||||
if (!path.rel().empty())
|
||||
dst /= path.rel();
|
||||
return dst;
|
||||
}
|
||||
|
||||
void RestoreSink::createDirectory(const CanonPath & path)
|
||||
{
|
||||
std::filesystem::create_directory(dstPath / path.rel());
|
||||
auto p = append(dstPath, path);
|
||||
if (!std::filesystem::create_directory(p))
|
||||
throw Error("path '%s' already exists", p.string());
|
||||
};
|
||||
|
||||
struct RestoreRegularFile : CreateRegularFileSink {
|
||||
|
@ -93,14 +102,6 @@ struct RestoreRegularFile : CreateRegularFileSink {
|
|||
void preallocateContents(uint64_t size) override;
|
||||
};
|
||||
|
||||
static std::filesystem::path append(const std::filesystem::path & src, const CanonPath & path)
|
||||
{
|
||||
auto dst = src;
|
||||
if (!path.rel().empty())
|
||||
dst /= path.rel();
|
||||
return dst;
|
||||
}
|
||||
|
||||
void RestoreSink::createRegularFile(const CanonPath & path, std::function<void(CreateRegularFileSink &)> func)
|
||||
{
|
||||
auto p = append(dstPath, path);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue