diff options
Diffstat (limited to 'src/zencore')
| -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) |