diff --git a/src/cryfs/filesystem/CryNode.cpp b/src/cryfs/filesystem/CryNode.cpp index 9b8c70ca..0d666085 100644 --- a/src/cryfs/filesystem/CryNode.cpp +++ b/src/cryfs/filesystem/CryNode.cpp @@ -62,7 +62,7 @@ void CryNode::rename(const bf::path &to) { if (old == boost::none) { throw FuseErrnoException(EIO); } - std::string oldName = old->name(); // Store, because the next line invalidates the 'old' object + std::string oldName = old->name(); // Store, because if targetDir == *_parent, then the 'old' object will be invalidated after we add something to targetDir if (oldName != to.filename().native()) { targetDir->AddChild(to.filename().native(), old->key(), old->type(), old->mode(), old->uid(), old->gid(), old->lastAccessTime(), old->lastModificationTime()); diff --git a/src/fspp/fstest/FsppNodeTest.h b/src/fspp/fstest/FsppNodeTest.h index efe4ca08..35e2032d 100644 --- a/src/fspp/fstest/FsppNodeTest.h +++ b/src/fspp/fstest/FsppNodeTest.h @@ -25,6 +25,20 @@ public: EXPECT_NE(boost::none, this->device->Load("/oldname")); } + void Test_Rename_TargetParentDirIsFile() { + auto node = CreateNode("/oldname"); + CreateFile("/somefile"); + try { + node->rename("/somefile/newname"); + EXPECT_TRUE(false); // Expect it throws an exception + } catch (const fspp::fuse::FuseErrnoException &e) { + EXPECT_EQ(ENOTDIR, e.getErrno()); + } + //Files should still exist + EXPECT_NE(boost::none, this->device->Load("/oldname")); + EXPECT_NE(boost::none, this->device->Load("/somefile")); + } + void Test_Rename_InRoot() { auto node = CreateNode("/oldname"); node->rename("/newname"); @@ -71,10 +85,24 @@ public: EXPECT_NE(boost::none, this->device->Load("/oldname")); } + void Test_Rename_RootDir() { + auto root = this->LoadDir("/"); + try { + root->rename("/newname"); + EXPECT_TRUE(false); // expect throws + } catch (const fspp::fuse::FuseErrnoException &e) { + EXPECT_EQ(EBUSY, e.getErrno()); + } + } + private: void CreateDir(const boost::filesystem::path &path) { this->LoadDir(path.parent_path())->createDir(path.filename().native(), this->MODE_PUBLIC, 0, 0); } + + void CreateFile(const boost::filesystem::path &path) { + this->LoadDir(path.parent_path())->createAndOpenFile(path.filename().native(), this->MODE_PUBLIC, 0, 0); + } }; template @@ -124,12 +152,14 @@ public: */ REGISTER_NODE_TEST_CASES( Rename_TargetParentDirDoesntExist, + Rename_TargetParentDirIsFile, Rename_InRoot, Rename_InNested, Rename_RootToNested, Rename_NestedToRoot, Rename_NestedToNested, - Rename_ToItself + Rename_ToItself, + Rename_RootDir ); #endif