aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2023-11-22 17:59:54 +0100
committerGitHub <[email protected]>2023-11-22 17:59:54 +0100
commit12342f51038dba30ad8b490493596c72d9306994 (patch)
treef86c93fc13f994579d47abc7a599112c0a2f2ea0 /src/zencore/filesystem.cpp
parentreduce work when there are no blocks to compact (#558) (diff)
downloadzen-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.cpp30
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)