OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <string> | |
6 | |
7 #include "base/basictypes.h" | |
8 #include "base/logging.h" | |
9 #include "testing/gtest/include/gtest/gtest.h" | |
10 #include "webkit/browser/fileapi/file_system_url.h" | |
11 #include "webkit/browser/fileapi/isolated_context.h" | |
12 | |
13 #define FPL(x) FILE_PATH_LITERAL(x) | |
14 | |
15 #if defined(FILE_PATH_USES_DRIVE_LETTERS) | |
16 #define DRIVE FPL("C:") | |
17 #else | |
18 #define DRIVE | |
19 #endif | |
20 | |
21 namespace fileapi { | |
22 | |
23 typedef IsolatedContext::MountPointInfo FileInfo; | |
24 | |
25 namespace { | |
26 | |
27 const base::FilePath kTestPaths[] = { | |
28 base::FilePath(DRIVE FPL("/a/b.txt")), | |
29 base::FilePath(DRIVE FPL("/c/d/e")), | |
30 base::FilePath(DRIVE FPL("/h/")), | |
31 base::FilePath(DRIVE FPL("/")), | |
32 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | |
33 base::FilePath(DRIVE FPL("\\foo\\bar")), | |
34 base::FilePath(DRIVE FPL("\\")), | |
35 #endif | |
36 // For duplicated base name test. | |
37 base::FilePath(DRIVE FPL("/")), | |
38 base::FilePath(DRIVE FPL("/f/e")), | |
39 base::FilePath(DRIVE FPL("/f/b.txt")), | |
40 }; | |
41 | |
42 } // namespace | |
43 | |
44 class IsolatedContextTest : public testing::Test { | |
45 public: | |
46 IsolatedContextTest() { | |
47 for (size_t i = 0; i < arraysize(kTestPaths); ++i) | |
48 fileset_.insert(kTestPaths[i].NormalizePathSeparators()); | |
49 } | |
50 | |
51 virtual void SetUp() { | |
52 IsolatedContext::FileInfoSet files; | |
53 for (size_t i = 0; i < arraysize(kTestPaths); ++i) { | |
54 std::string name; | |
55 ASSERT_TRUE( | |
56 files.AddPath(kTestPaths[i].NormalizePathSeparators(), &name)); | |
57 names_.push_back(name); | |
58 } | |
59 id_ = IsolatedContext::GetInstance()->RegisterDraggedFileSystem(files); | |
60 IsolatedContext::GetInstance()->AddReference(id_); | |
61 ASSERT_FALSE(id_.empty()); | |
62 } | |
63 | |
64 virtual void TearDown() { | |
65 IsolatedContext::GetInstance()->RemoveReference(id_); | |
66 } | |
67 | |
68 IsolatedContext* isolated_context() const { | |
69 return IsolatedContext::GetInstance(); | |
70 } | |
71 | |
72 protected: | |
73 std::string id_; | |
74 std::multiset<base::FilePath> fileset_; | |
75 std::vector<std::string> names_; | |
76 | |
77 private: | |
78 DISALLOW_COPY_AND_ASSIGN(IsolatedContextTest); | |
79 }; | |
80 | |
81 TEST_F(IsolatedContextTest, RegisterAndRevokeTest) { | |
82 // See if the returned top-level entries match with what we registered. | |
83 std::vector<FileInfo> toplevels; | |
84 ASSERT_TRUE(isolated_context()->GetDraggedFileInfo(id_, &toplevels)); | |
85 ASSERT_EQ(fileset_.size(), toplevels.size()); | |
86 for (size_t i = 0; i < toplevels.size(); ++i) { | |
87 ASSERT_TRUE(fileset_.find(toplevels[i].path) != fileset_.end()); | |
88 } | |
89 | |
90 // See if the name of each registered kTestPaths (that is what we | |
91 // register in SetUp() by RegisterDraggedFileSystem) is properly cracked as | |
92 // a valid virtual path in the isolated filesystem. | |
93 for (size_t i = 0; i < arraysize(kTestPaths); ++i) { | |
94 base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_) | |
95 .AppendASCII(names_[i]); | |
96 std::string cracked_id; | |
97 base::FilePath cracked_path; | |
98 FileSystemType cracked_type; | |
99 FileSystemMountOption cracked_option; | |
100 ASSERT_TRUE(isolated_context()->CrackVirtualPath( | |
101 virtual_path, &cracked_id, &cracked_type, &cracked_path, | |
102 &cracked_option)); | |
103 ASSERT_EQ(kTestPaths[i].NormalizePathSeparators().value(), | |
104 cracked_path.value()); | |
105 ASSERT_EQ(id_, cracked_id); | |
106 ASSERT_EQ(kFileSystemTypeDragged, cracked_type); | |
107 } | |
108 | |
109 // Make sure GetRegisteredPath returns false for id_ since it is | |
110 // registered for dragged files. | |
111 base::FilePath path; | |
112 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path)); | |
113 | |
114 // Deref the current one and registering a new one. | |
115 isolated_context()->RemoveReference(id_); | |
116 | |
117 std::string id2 = isolated_context()->RegisterFileSystemForPath( | |
118 kFileSystemTypeNativeLocal, base::FilePath(DRIVE FPL("/foo")), NULL); | |
119 | |
120 // Make sure the GetDraggedFileInfo returns false for both ones. | |
121 ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id2, &toplevels)); | |
122 ASSERT_FALSE(isolated_context()->GetDraggedFileInfo(id_, &toplevels)); | |
123 | |
124 // Make sure the GetRegisteredPath returns true only for the new one. | |
125 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id_, &path)); | |
126 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path)); | |
127 | |
128 // Try registering three more file systems for the same path as id2. | |
129 std::string id3 = isolated_context()->RegisterFileSystemForPath( | |
130 kFileSystemTypeNativeLocal, path, NULL); | |
131 std::string id4 = isolated_context()->RegisterFileSystemForPath( | |
132 kFileSystemTypeNativeLocal, path, NULL); | |
133 std::string id5 = isolated_context()->RegisterFileSystemForPath( | |
134 kFileSystemTypeNativeLocal, path, NULL); | |
135 | |
136 // Remove file system for id4. | |
137 isolated_context()->AddReference(id4); | |
138 isolated_context()->RemoveReference(id4); | |
139 | |
140 // Only id4 should become invalid now. | |
141 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path)); | |
142 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path)); | |
143 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path)); | |
144 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id5, &path)); | |
145 | |
146 // Revoke file system id5, after adding multiple references. | |
147 isolated_context()->AddReference(id5); | |
148 isolated_context()->AddReference(id5); | |
149 isolated_context()->AddReference(id5); | |
150 isolated_context()->RevokeFileSystem(id5); | |
151 | |
152 // No matter how many references we add id5 must be invalid now. | |
153 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id2, &path)); | |
154 ASSERT_TRUE(isolated_context()->GetRegisteredPath(id3, &path)); | |
155 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path)); | |
156 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path)); | |
157 | |
158 // Revoke the file systems by path. | |
159 isolated_context()->RevokeFileSystemByPath(path); | |
160 | |
161 // Now all the file systems associated to the path must be invalid. | |
162 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id2, &path)); | |
163 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id3, &path)); | |
164 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id4, &path)); | |
165 ASSERT_FALSE(isolated_context()->GetRegisteredPath(id5, &path)); | |
166 } | |
167 | |
168 TEST_F(IsolatedContextTest, CrackWithRelativePaths) { | |
169 const struct { | |
170 base::FilePath::StringType path; | |
171 bool valid; | |
172 } relatives[] = { | |
173 { FPL("foo"), true }, | |
174 { FPL("foo/bar"), true }, | |
175 { FPL(".."), false }, | |
176 { FPL("foo/.."), false }, | |
177 { FPL("foo/../bar"), false }, | |
178 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | |
179 # define SHOULD_FAIL_WITH_WIN_SEPARATORS false | |
180 #else | |
181 # define SHOULD_FAIL_WITH_WIN_SEPARATORS true | |
182 #endif | |
183 { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, | |
184 { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, | |
185 }; | |
186 | |
187 for (size_t i = 0; i < arraysize(kTestPaths); ++i) { | |
188 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(relatives); ++j) { | |
189 SCOPED_TRACE(testing::Message() << "Testing " | |
190 << kTestPaths[i].value() << " " << relatives[j].path); | |
191 base::FilePath virtual_path = | |
192 isolated_context()->CreateVirtualRootPath(id_).AppendASCII( | |
193 names_[i]).Append(relatives[j].path); | |
194 std::string cracked_id; | |
195 base::FilePath cracked_path; | |
196 FileSystemType cracked_type; | |
197 FileSystemMountOption cracked_option; | |
198 if (!relatives[j].valid) { | |
199 ASSERT_FALSE(isolated_context()->CrackVirtualPath( | |
200 virtual_path, &cracked_id, &cracked_type, &cracked_path, | |
201 &cracked_option)); | |
202 continue; | |
203 } | |
204 ASSERT_TRUE(isolated_context()->CrackVirtualPath( | |
205 virtual_path, &cracked_id, &cracked_type, &cracked_path, | |
206 &cracked_option)); | |
207 ASSERT_EQ(kTestPaths[i].Append(relatives[j].path) | |
208 .NormalizePathSeparators().value(), | |
209 cracked_path.value()); | |
210 ASSERT_EQ(id_, cracked_id); | |
211 ASSERT_EQ(kFileSystemTypeDragged, cracked_type); | |
212 } | |
213 } | |
214 } | |
215 | |
216 TEST_F(IsolatedContextTest, CrackURLWithRelativePaths) { | |
217 const struct { | |
218 base::FilePath::StringType path; | |
219 bool valid; | |
220 } relatives[] = { | |
221 { FPL("foo"), true }, | |
222 { FPL("foo/bar"), true }, | |
223 { FPL(".."), false }, | |
224 { FPL("foo/.."), false }, | |
225 { FPL("foo/../bar"), false }, | |
226 #if defined(FILE_PATH_USES_WIN_SEPARATORS) | |
227 # define SHOULD_FAIL_WITH_WIN_SEPARATORS false | |
228 #else | |
229 # define SHOULD_FAIL_WITH_WIN_SEPARATORS true | |
230 #endif | |
231 { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, | |
232 { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, | |
233 }; | |
234 | |
235 for (size_t i = 0; i < arraysize(kTestPaths); ++i) { | |
236 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(relatives); ++j) { | |
237 SCOPED_TRACE(testing::Message() << "Testing " | |
238 << kTestPaths[i].value() << " " << relatives[j].path); | |
239 base::FilePath virtual_path = | |
240 isolated_context()->CreateVirtualRootPath(id_).AppendASCII( | |
241 names_[i]).Append(relatives[j].path); | |
242 | |
243 FileSystemURL cracked = isolated_context()->CreateCrackedFileSystemURL( | |
244 GURL("http://chromium.org"), kFileSystemTypeIsolated, virtual_path); | |
245 | |
246 ASSERT_EQ(relatives[j].valid, cracked.is_valid()); | |
247 | |
248 if (!relatives[j].valid) | |
249 continue; | |
250 ASSERT_EQ(GURL("http://chromium.org"), cracked.origin()); | |
251 ASSERT_EQ(kTestPaths[i].Append(relatives[j].path) | |
252 .NormalizePathSeparators().value(), | |
253 cracked.path().value()); | |
254 ASSERT_EQ(virtual_path.NormalizePathSeparators(), cracked.virtual_path()); | |
255 ASSERT_EQ(id_, cracked.filesystem_id()); | |
256 ASSERT_EQ(kFileSystemTypeDragged, cracked.type()); | |
257 ASSERT_EQ(kFileSystemTypeIsolated, cracked.mount_type()); | |
258 } | |
259 } | |
260 } | |
261 | |
262 TEST_F(IsolatedContextTest, TestWithVirtualRoot) { | |
263 std::string cracked_id; | |
264 base::FilePath cracked_path; | |
265 FileSystemMountOption cracked_option; | |
266 | |
267 // Trying to crack virtual root "/" returns true but with empty cracked path | |
268 // as "/" of the isolated filesystem is a pure virtual directory | |
269 // that has no corresponding platform directory. | |
270 base::FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_); | |
271 ASSERT_TRUE(isolated_context()->CrackVirtualPath( | |
272 virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option)); | |
273 ASSERT_EQ(FPL(""), cracked_path.value()); | |
274 ASSERT_EQ(id_, cracked_id); | |
275 | |
276 // Trying to crack "/foo" should fail (because "foo" is not the one | |
277 // included in the kTestPaths). | |
278 virtual_path = isolated_context()->CreateVirtualRootPath( | |
279 id_).AppendASCII("foo"); | |
280 ASSERT_FALSE(isolated_context()->CrackVirtualPath( | |
281 virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option)); | |
282 } | |
283 | |
284 TEST_F(IsolatedContextTest, CanHandleURL) { | |
285 const GURL test_origin("http://chromium.org"); | |
286 const base::FilePath test_path(FPL("/mount")); | |
287 | |
288 // Should handle isolated file system. | |
289 EXPECT_TRUE(isolated_context()->HandlesFileSystemMountType( | |
290 fileapi::kFileSystemTypeIsolated)); | |
291 | |
292 // Shouldn't handle the rest. | |
293 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
294 fileapi::kFileSystemTypeExternal)); | |
295 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
296 fileapi::kFileSystemTypeTemporary)); | |
297 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
298 fileapi::kFileSystemTypePersistent)); | |
299 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
300 fileapi::kFileSystemTypeTest)); | |
301 // Not even if it's isolated subtype. | |
302 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
303 fileapi::kFileSystemTypeNativeLocal)); | |
304 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
305 fileapi::kFileSystemTypeDragged)); | |
306 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
307 fileapi::kFileSystemTypeNativeMedia)); | |
308 EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( | |
309 fileapi::kFileSystemTypeDeviceMedia)); | |
310 } | |
311 | |
312 TEST_F(IsolatedContextTest, VirtualFileSystemTests) { | |
313 // Should be able to register empty and non-absolute paths | |
314 std::string empty_fsid = isolated_context()->RegisterFileSystemForVirtualPath( | |
315 fileapi::kFileSystemTypeIsolated, "_", base::FilePath()); | |
316 std::string relative_fsid = | |
317 isolated_context()->RegisterFileSystemForVirtualPath( | |
318 fileapi::kFileSystemTypeIsolated, "_", | |
319 base::FilePath(FPL("relpath"))); | |
320 ASSERT_FALSE(empty_fsid.empty()); | |
321 ASSERT_FALSE(relative_fsid.empty()); | |
322 | |
323 // Make sure that filesystem root is not prepended to cracked virtual paths. | |
324 base::FilePath database_root = base::FilePath(DRIVE FPL("/database_path")); | |
325 std::string database_fsid = | |
326 isolated_context()->RegisterFileSystemForVirtualPath( | |
327 fileapi::kFileSystemTypeIsolated, "_", database_root); | |
328 | |
329 base::FilePath test_virtual_path = | |
330 base::FilePath().AppendASCII("virtualdir").AppendASCII("virtualfile.txt"); | |
331 | |
332 base::FilePath whole_virtual_path = | |
333 isolated_context()->CreateVirtualRootPath(database_fsid) | |
334 .AppendASCII("_").Append(test_virtual_path); | |
335 | |
336 std::string cracked_id; | |
337 base::FilePath cracked_path; | |
338 FileSystemMountOption cracked_option; | |
339 ASSERT_TRUE(isolated_context()->CrackVirtualPath( | |
340 whole_virtual_path, &cracked_id, NULL, &cracked_path, &cracked_option)); | |
341 ASSERT_EQ(database_fsid, cracked_id); | |
342 ASSERT_EQ(test_virtual_path, cracked_path); | |
343 } | |
344 | |
345 } // namespace fileapi | |
OLD | NEW |