Skip to content

Commit 587d0de

Browse files
Merge pull request #57 from awslabs/DirectoryTraversal
Directory traversal (Directory Upload and Directory Download for transfer manager).
2 parents 532801a + c704abd commit 587d0de

File tree

11 files changed

+1314
-23
lines changed

11 files changed

+1314
-23
lines changed

aws-cpp-sdk-core-tests/utils/FileSystemUtilsTest.cpp

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
#include <aws/core/platform/FileSystem.h>
1717
#include <aws/core/utils/FileSystemUtils.h>
18+
#include <aws/core/utils/memory/stl/AWSSet.h>
1819
#include <aws/external/gtest.h>
1920
#include <aws/testing/MemoryTesting.h>
2021

@@ -30,6 +31,13 @@ TEST(FileTest, HomeDirectory)
3031
ASSERT_TRUE(homeDirectory.size() > 0);
3132
}
3233

34+
TEST(FileTest, TestInvalidDirectoryPath)
35+
{
36+
auto badDir = Aws::FileSystem::OpenDirectory("boogieMan");
37+
bool dirGood = *badDir;
38+
ASSERT_FALSE(dirGood);
39+
}
40+
3341
TEST(FileTest, TempFile)
3442
{
3543
Aws::String filePath;
@@ -55,3 +63,170 @@ TEST(FileTest, TempFile)
5563
std::ifstream testIn(filePath.c_str());
5664
ASSERT_FALSE(testIn.good());
5765
}
66+
67+
class DirectoryTreeTest : public ::testing::Test
68+
{
69+
public:
70+
Aws::String dir1, dir2, file1, file2;
71+
bool dir1Created, dir2Created;
72+
size_t file1Size, file2Size;
73+
74+
DirectoryTreeTest() : dir1Created(false), dir2Created(false), file1Size(0), file2Size(0) {}
75+
76+
void SetUp() override
77+
{
78+
auto homeDirectory = Aws::FileSystem::GetHomeDirectory();
79+
ASSERT_FALSE(homeDirectory.empty());
80+
81+
dir1 = Aws::FileSystem::Join(homeDirectory, "dir1");
82+
dir2 = Aws::FileSystem::Join(dir1, "dir2");
83+
84+
file1 = Aws::FileSystem::Join(dir1, "file1");
85+
file2 = Aws::FileSystem::Join(dir2, "file2");
86+
87+
dir1Created = Aws::FileSystem::CreateDirectoryIfNotExists(dir1.c_str());
88+
ASSERT_TRUE(dir1Created);
89+
90+
dir2Created = Aws::FileSystem::CreateDirectoryIfNotExists(dir2.c_str());
91+
ASSERT_TRUE(dir2Created);
92+
93+
{
94+
Aws::OFStream file1Stream(file1.c_str());
95+
ASSERT_TRUE(file1Stream.good());
96+
file1Stream << "Test Data1" << std::endl;
97+
file1Stream.seekp(0, std::ios_base::end);
98+
file1Size = static_cast<size_t>(file1Stream.tellp());
99+
}
100+
101+
{
102+
Aws::OFStream file2Stream(file2.c_str());
103+
ASSERT_TRUE(file2Stream.good());
104+
file2Stream << "Test Data2" << std::endl;
105+
file2Stream.seekp(0, std::ios_base::end);
106+
file2Size = static_cast<size_t>(file2Stream.tellp());
107+
}
108+
}
109+
110+
void TearDown() override
111+
{
112+
Aws::FileSystem::DeepDeleteDirectory(dir1.c_str());
113+
}
114+
};
115+
116+
TEST_F(DirectoryTreeTest, TestManualDirectoryTraversal)
117+
{
118+
//let one have the delimiter after it just to make sure both paths get handled.
119+
auto dir1WithExtraDelimiter = dir1 + Aws::FileSystem::PATH_DELIM;
120+
auto dir = Aws::FileSystem::OpenDirectory(dir1WithExtraDelimiter);
121+
122+
ASSERT_STREQ(dir1.c_str(), dir->GetPath().c_str());
123+
ASSERT_TRUE(dir->operator bool());
124+
125+
auto entry = dir->Next();
126+
Aws::FileSystem::DirectoryEntry dir2Entry;
127+
Aws::FileSystem::DirectoryEntry file1Entry;
128+
129+
if (entry.fileType == Aws::FileSystem::FileType::File)
130+
{
131+
file1Entry = entry;
132+
dir2Entry = dir->Next();
133+
}
134+
else
135+
{
136+
dir2Entry = entry;
137+
file1Entry = dir->Next();
138+
}
139+
140+
ASSERT_EQ(Aws::FileSystem::FileType::Directory, dir2Entry.fileType);
141+
ASSERT_STREQ(dir2.c_str(), dir2Entry.path.c_str());
142+
143+
auto& nextDir = dir->Descend(dir2Entry);
144+
ASSERT_STREQ(dir2.c_str(), nextDir.GetPath().c_str());
145+
146+
entry = nextDir.Next();
147+
ASSERT_EQ(Aws::FileSystem::FileType::File, entry.fileType);
148+
ASSERT_STREQ(file2.c_str(), entry.path.c_str());
149+
ASSERT_EQ(static_cast<int64_t>(file2Size), entry.fileSize);
150+
ASSERT_TRUE(entry.operator bool());
151+
152+
entry = nextDir.Next();
153+
ASSERT_FALSE(entry.operator bool());
154+
155+
ASSERT_EQ(Aws::FileSystem::FileType::File, file1Entry.fileType);
156+
ASSERT_STREQ(file1.c_str(), file1Entry.path.c_str());
157+
ASSERT_EQ(static_cast<int64_t>(file1Size), file1Entry.fileSize);
158+
ASSERT_TRUE(file1Entry.operator bool());
159+
160+
entry = dir->Next();
161+
ASSERT_FALSE(entry.operator bool());
162+
}
163+
164+
TEST_F(DirectoryTreeTest, TestDirectoryTreeDepthFirstTraversal)
165+
{
166+
Aws::FileSystem::DirectoryTree tree(dir1);
167+
168+
Aws::Set<Aws::String> paths({dir2, file1, file2});
169+
170+
auto visitor = [&](const Aws::FileSystem::DirectoryTree*, const Aws::FileSystem::DirectoryEntry& entry) { paths.erase(entry.path); return true; };
171+
172+
tree.TraverseDepthFirst(visitor);
173+
174+
ASSERT_TRUE(paths.empty());
175+
}
176+
177+
TEST_F(DirectoryTreeTest, TestDirectoryTreeEqualityOperator)
178+
{
179+
Aws::FileSystem::DirectoryTree tree(dir1);
180+
181+
Aws::String comparisonDirectory = Aws::FileSystem::Join(Aws::FileSystem::GetHomeDirectory(), "compDir");
182+
ASSERT_TRUE(Aws::FileSystem::DeepCopyDirectory(dir1.c_str(), comparisonDirectory.c_str()));
183+
EXPECT_TRUE(tree == comparisonDirectory);
184+
ASSERT_TRUE(Aws::FileSystem::DeepDeleteDirectory(comparisonDirectory.c_str()));
185+
}
186+
187+
TEST_F(DirectoryTreeTest, TestDirectoryTreeDiff)
188+
{
189+
Aws::FileSystem::DirectoryTree tree(dir1);
190+
191+
Aws::String comparisonDirectory = Aws::FileSystem::Join(Aws::FileSystem::GetHomeDirectory(), "compDir");
192+
ASSERT_TRUE(Aws::FileSystem::DeepCopyDirectory(dir1.c_str(), comparisonDirectory.c_str()));
193+
194+
{
195+
Aws::FileSystem::DirectoryTree comparisonTree(comparisonDirectory);
196+
auto diff = tree.Diff(comparisonTree);
197+
ASSERT_EQ(0u, diff.size());
198+
}
199+
200+
auto additionalFile = Aws::FileSystem::Join(comparisonDirectory, "additionalFile");
201+
{
202+
Aws::OFStream additionalFileStrm(additionalFile.c_str());
203+
ASSERT_TRUE(additionalFileStrm.good());
204+
additionalFileStrm << "Additional File input." << std::endl;
205+
}
206+
207+
auto missingFile = Aws::FileSystem::Join(Aws::FileSystem::Join(comparisonDirectory, "dir2"), "file2");
208+
Aws::FileSystem::RemoveFileIfExists(missingFile.c_str());
209+
210+
Aws::FileSystem::DirectoryTree comparisonTree(comparisonDirectory);
211+
auto diff = tree.Diff(comparisonTree);
212+
Aws::FileSystem::DeepDeleteDirectory(comparisonDirectory.c_str());
213+
214+
ASSERT_EQ(2u, diff.size());
215+
auto entry = diff.begin();
216+
ASSERT_STREQ(additionalFile.c_str(), entry->second.path.c_str());
217+
entry++;
218+
ASSERT_STREQ(file2.c_str(), entry->second.path.c_str());
219+
}
220+
221+
TEST_F(DirectoryTreeTest, TestDirectoryTreeBreadthFirstTraversal)
222+
{
223+
Aws::FileSystem::DirectoryTree tree(dir1);
224+
225+
Aws::Set<Aws::String> paths({ dir2, file1, file2 });
226+
227+
auto visitor = [&](const Aws::FileSystem::DirectoryTree*, const Aws::FileSystem::DirectoryEntry& entry) { paths.erase(entry.path); return true; };
228+
229+
tree.TraverseBreadthFirst(visitor);
230+
231+
ASSERT_TRUE(paths.empty());
232+
}

aws-cpp-sdk-core/include/aws/core/VersionConfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,4 @@
1313
* permissions and limitations under the License.
1414
*/
1515

16-
#define AWS_SDK_VERSION_STRING "1.0.44"
16+
#define AWS_SDK_VERSION_STRING "1.0.44"

0 commit comments

Comments
 (0)