diff options
| author | Stefan Boberg <[email protected]> | 2023-11-22 17:59:54 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-22 17:59:54 +0100 |
| commit | 12342f51038dba30ad8b490493596c72d9306994 (patch) | |
| tree | f86c93fc13f994579d47abc7a599112c0a2f2ea0 /src/zencore/filesystem.cpp | |
| parent | reduce work when there are no blocks to compact (#558) (diff) | |
| download | zen-12342f51038dba30ad8b490493596c72d9306994.tar.xz zen-12342f51038dba30ad8b490493596c72d9306994.zip | |
fix block cloning copy argument validation (#560)
Diffstat (limited to 'src/zencore/filesystem.cpp')
| -rw-r--r-- | src/zencore/filesystem.cpp | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index f117001b5..85f7690bd 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -624,6 +624,9 @@ CopyTree(std::filesystem::path FromPath, std::filesystem::path ToPath, const Cop if (ToPath.empty()) throw std::runtime_error("no CopyTree target specified"); + if (Options.MustClone && !SupportsBlockRefCounting(FromPath)) + throw std::runtime_error(fmt::format("cloning not possible from '{}'", FromPath)); + if (std::filesystem::exists(ToPath)) { if (!std::filesystem::is_directory(ToPath)) @@ -636,6 +639,33 @@ CopyTree(std::filesystem::path FromPath, std::filesystem::path ToPath, const Cop std::filesystem::create_directories(ToPath); } + if (Options.MustClone && !SupportsBlockRefCounting(ToPath)) + throw std::runtime_error(fmt::format("cloning not possible from '{}'", ToPath)); + + // Verify source/target relationships + + std::error_code Ec; + std::filesystem::path FromCanonical = std::filesystem::canonical(FromPath, Ec); + + if (!Ec) + { + std::filesystem::path ToCanonical = std::filesystem::canonical(ToPath, Ec); + + if (!Ec) + { + if (FromCanonical == ToCanonical) + { + throw std::runtime_error("Target and source must be distinct files or directories"); + } + + if (ToCanonical.generic_string().starts_with(FromCanonical.generic_string()) || + FromCanonical.generic_string().starts_with(ToCanonical.generic_string())) + { + throw std::runtime_error("Invalid parent/child relationship for source/target directories"); + } + } + } + struct CopyVisitor : public FileSystemTraversal::TreeVisitor { CopyVisitor(std::filesystem::path InBasePath, zen::CopyFileOptions InCopyOptions) : BasePath(InBasePath), CopyOptions(InCopyOptions) |