| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "webkit/browser/fileapi/sandbox_file_system_backend.h" | 5 #include "webkit/browser/fileapi/sandbox_file_system_backend.h" |
| 6 | 6 |
| 7 #include <set> | 7 #include <set> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/file_util.h" | 10 #include "base/file_util.h" |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 78 base::PlatformFileError error) { | 78 base::PlatformFileError error) { |
| 79 *error_out = error; | 79 *error_out = error; |
| 80 } | 80 } |
| 81 | 81 |
| 82 } // namespace | 82 } // namespace |
| 83 | 83 |
| 84 class SandboxFileSystemBackendTest : public testing::Test { | 84 class SandboxFileSystemBackendTest : public testing::Test { |
| 85 protected: | 85 protected: |
| 86 virtual void SetUp() { | 86 virtual void SetUp() { |
| 87 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); | 87 ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); |
| 88 SetUpNewSandboxContext(CreateAllowFileAccessOptions()); |
| 89 } |
| 90 |
| 91 void SetUpNewSandboxContext(const FileSystemOptions& options) { |
| 88 context_.reset(new SandboxContext( | 92 context_.reset(new SandboxContext( |
| 89 NULL /* quota_manager_proxy */, | 93 NULL /* quota_manager_proxy */, |
| 90 base::MessageLoopProxy::current().get(), | 94 base::MessageLoopProxy::current().get(), |
| 91 data_dir_.path(), | 95 data_dir_.path(), |
| 92 NULL /* special_storage_policy */)); | 96 NULL /* special_storage_policy */, |
| 97 options)); |
| 93 } | 98 } |
| 94 | 99 |
| 95 void SetUpNewBackend(const FileSystemOptions& options) { | 100 void SetUpNewBackend(const FileSystemOptions& options) { |
| 96 backend_.reset(new SandboxFileSystemBackend(context_.get(), options)); | 101 SetUpNewSandboxContext(options); |
| 102 backend_.reset(new SandboxFileSystemBackend(context_.get())); |
| 97 } | 103 } |
| 98 | 104 |
| 99 SandboxFileSystemBackend::OriginEnumerator* CreateOriginEnumerator() const { | 105 SandboxContext::OriginEnumerator* CreateOriginEnumerator() const { |
| 100 return backend_->CreateOriginEnumerator(); | 106 return backend_->CreateOriginEnumerator(); |
| 101 } | 107 } |
| 102 | 108 |
| 103 void CreateOriginTypeDirectory(const GURL& origin, | 109 void CreateOriginTypeDirectory(const GURL& origin, |
| 104 fileapi::FileSystemType type) { | 110 fileapi::FileSystemType type) { |
| 105 base::FilePath target = backend_-> | 111 base::FilePath target = context_-> |
| 106 GetBaseDirectoryForOriginAndType(origin, type, true); | 112 GetBaseDirectoryForOriginAndType(origin, type, true); |
| 107 ASSERT_TRUE(!target.empty()); | 113 ASSERT_TRUE(!target.empty()); |
| 108 ASSERT_TRUE(base::DirectoryExists(target)); | 114 ASSERT_TRUE(base::DirectoryExists(target)); |
| 109 } | 115 } |
| 110 | 116 |
| 111 bool GetRootPath(const GURL& origin_url, | 117 bool GetRootPath(const GURL& origin_url, |
| 112 fileapi::FileSystemType type, | 118 fileapi::FileSystemType type, |
| 113 OpenFileSystemMode mode, | 119 OpenFileSystemMode mode, |
| 114 base::FilePath* root_path) { | 120 base::FilePath* root_path) { |
| 115 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 121 base::PlatformFileError error = base::PLATFORM_FILE_OK; |
| 116 backend_->OpenFileSystem( | 122 backend_->OpenFileSystem( |
| 117 origin_url, type, mode, | 123 origin_url, type, mode, |
| 118 base::Bind(&DidOpenFileSystem, &error)); | 124 base::Bind(&DidOpenFileSystem, &error)); |
| 119 base::MessageLoop::current()->RunUntilIdle(); | 125 base::MessageLoop::current()->RunUntilIdle(); |
| 120 if (error != base::PLATFORM_FILE_OK) | 126 if (error != base::PLATFORM_FILE_OK) |
| 121 return false; | 127 return false; |
| 122 base::FilePath returned_root_path = | 128 base::FilePath returned_root_path = |
| 123 backend_->GetBaseDirectoryForOriginAndType( | 129 context_->GetBaseDirectoryForOriginAndType( |
| 124 origin_url, type, false /* create */); | 130 origin_url, type, false /* create */); |
| 125 if (root_path) | 131 if (root_path) |
| 126 *root_path = returned_root_path; | 132 *root_path = returned_root_path; |
| 127 return !returned_root_path.empty(); | 133 return !returned_root_path.empty(); |
| 128 } | 134 } |
| 129 | 135 |
| 130 base::FilePath file_system_path() const { | 136 base::FilePath file_system_path() const { |
| 131 return data_dir_.path().Append(SandboxContext::kFileSystemDirectory); | 137 return data_dir_.path().Append(SandboxContext::kFileSystemDirectory); |
| 132 } | 138 } |
| 133 | 139 |
| 134 base::ScopedTempDir data_dir_; | 140 base::ScopedTempDir data_dir_; |
| 135 base::MessageLoop message_loop_; | 141 base::MessageLoop message_loop_; |
| 136 scoped_ptr<SandboxContext> context_; | 142 scoped_ptr<SandboxContext> context_; |
| 137 scoped_ptr<SandboxFileSystemBackend> backend_; | 143 scoped_ptr<SandboxFileSystemBackend> backend_; |
| 138 }; | 144 }; |
| 139 | 145 |
| 140 TEST_F(SandboxFileSystemBackendTest, Empty) { | 146 TEST_F(SandboxFileSystemBackendTest, Empty) { |
| 141 SetUpNewBackend(CreateAllowFileAccessOptions()); | 147 SetUpNewBackend(CreateAllowFileAccessOptions()); |
| 142 scoped_ptr<SandboxFileSystemBackend::OriginEnumerator> enumerator( | 148 scoped_ptr<SandboxContext::OriginEnumerator> enumerator( |
| 143 CreateOriginEnumerator()); | 149 CreateOriginEnumerator()); |
| 144 ASSERT_TRUE(enumerator->Next().is_empty()); | 150 ASSERT_TRUE(enumerator->Next().is_empty()); |
| 145 } | 151 } |
| 146 | 152 |
| 147 TEST_F(SandboxFileSystemBackendTest, EnumerateOrigins) { | 153 TEST_F(SandboxFileSystemBackendTest, EnumerateOrigins) { |
| 148 SetUpNewBackend(CreateAllowFileAccessOptions()); | 154 SetUpNewBackend(CreateAllowFileAccessOptions()); |
| 149 const char* temporary_origins[] = { | 155 const char* temporary_origins[] = { |
| 150 "http://www.bar.com/", | 156 "http://www.bar.com/", |
| 151 "http://www.foo.com/", | 157 "http://www.foo.com/", |
| 152 "http://www.foo.com:1/", | 158 "http://www.foo.com:1/", |
| (...skipping 12 matching lines...) Expand all Loading... |
| 165 CreateOriginTypeDirectory(GURL(temporary_origins[i]), | 171 CreateOriginTypeDirectory(GURL(temporary_origins[i]), |
| 166 fileapi::kFileSystemTypeTemporary); | 172 fileapi::kFileSystemTypeTemporary); |
| 167 temporary_set.insert(GURL(temporary_origins[i])); | 173 temporary_set.insert(GURL(temporary_origins[i])); |
| 168 } | 174 } |
| 169 for (size_t i = 0; i < persistent_size; ++i) { | 175 for (size_t i = 0; i < persistent_size; ++i) { |
| 170 CreateOriginTypeDirectory(GURL(persistent_origins[i]), | 176 CreateOriginTypeDirectory(GURL(persistent_origins[i]), |
| 171 kFileSystemTypePersistent); | 177 kFileSystemTypePersistent); |
| 172 persistent_set.insert(GURL(persistent_origins[i])); | 178 persistent_set.insert(GURL(persistent_origins[i])); |
| 173 } | 179 } |
| 174 | 180 |
| 175 scoped_ptr<SandboxFileSystemBackend::OriginEnumerator> enumerator( | 181 scoped_ptr<SandboxContext::OriginEnumerator> enumerator( |
| 176 CreateOriginEnumerator()); | 182 CreateOriginEnumerator()); |
| 177 size_t temporary_actual_size = 0; | 183 size_t temporary_actual_size = 0; |
| 178 size_t persistent_actual_size = 0; | 184 size_t persistent_actual_size = 0; |
| 179 GURL current; | 185 GURL current; |
| 180 while (!(current = enumerator->Next()).is_empty()) { | 186 while (!(current = enumerator->Next()).is_empty()) { |
| 181 SCOPED_TRACE(testing::Message() << "EnumerateOrigin " << current.spec()); | 187 SCOPED_TRACE(testing::Message() << "EnumerateOrigin " << current.spec()); |
| 182 if (enumerator->HasFileSystemType(kFileSystemTypeTemporary)) { | 188 if (enumerator->HasFileSystemType(kFileSystemTypeTemporary)) { |
| 183 ASSERT_TRUE(temporary_set.find(current) != temporary_set.end()); | 189 ASSERT_TRUE(temporary_set.find(current) != temporary_set.end()); |
| 184 ++temporary_actual_size; | 190 ++temporary_actual_size; |
| 185 } | 191 } |
| 186 if (enumerator->HasFileSystemType(kFileSystemTypePersistent)) { | 192 if (enumerator->HasFileSystemType(kFileSystemTypePersistent)) { |
| 187 ASSERT_TRUE(persistent_set.find(current) != persistent_set.end()); | 193 ASSERT_TRUE(persistent_set.find(current) != persistent_set.end()); |
| 188 ++persistent_actual_size; | 194 ++persistent_actual_size; |
| 189 } | 195 } |
| 190 } | 196 } |
| 191 | 197 |
| 192 EXPECT_EQ(temporary_size, temporary_actual_size); | 198 EXPECT_EQ(temporary_size, temporary_actual_size); |
| 193 EXPECT_EQ(persistent_size, persistent_actual_size); | 199 EXPECT_EQ(persistent_size, persistent_actual_size); |
| 194 } | 200 } |
| 195 | 201 |
| 196 TEST_F(SandboxFileSystemBackendTest, IsAccessValid) { | |
| 197 SetUpNewBackend(CreateAllowFileAccessOptions()); | |
| 198 | |
| 199 // Normal case. | |
| 200 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL("a"))); | |
| 201 | |
| 202 // Access to a path with parent references ('..') should be disallowed. | |
| 203 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL("a/../b"))); | |
| 204 | |
| 205 // Access from non-allowed scheme should be disallowed. | |
| 206 EXPECT_FALSE(backend_->IsAccessValid( | |
| 207 FileSystemURL::CreateForTest( | |
| 208 GURL("unknown://bar"), kFileSystemTypeTemporary, | |
| 209 base::FilePath::FromUTF8Unsafe("foo")))); | |
| 210 | |
| 211 // Access for non-sandbox type should be disallowed. | |
| 212 EXPECT_FALSE(backend_->IsAccessValid( | |
| 213 FileSystemURL::CreateForTest( | |
| 214 GURL("http://foo/"), kFileSystemTypeTest, | |
| 215 base::FilePath::FromUTF8Unsafe("foo")))); | |
| 216 | |
| 217 // Access with restricted name should be disallowed. | |
| 218 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL("."))); | |
| 219 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL(".."))); | |
| 220 | |
| 221 // This is also diallowed due to Windows XP parent path handling. | |
| 222 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL("..."))); | |
| 223 | |
| 224 // These are identified as unsafe cases due to weird path handling | |
| 225 // on Windows. | |
| 226 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL(" .."))); | |
| 227 EXPECT_FALSE(backend_->IsAccessValid(CreateFileSystemURL(".. "))); | |
| 228 | |
| 229 // Similar but safe cases. | |
| 230 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL(" ."))); | |
| 231 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL(". "))); | |
| 232 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL("b."))); | |
| 233 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL(".b"))); | |
| 234 | |
| 235 // A path that looks like a drive letter. | |
| 236 EXPECT_TRUE(backend_->IsAccessValid(CreateFileSystemURL("c:"))); | |
| 237 } | |
| 238 | |
| 239 TEST_F(SandboxFileSystemBackendTest, GetRootPathCreateAndExamine) { | 202 TEST_F(SandboxFileSystemBackendTest, GetRootPathCreateAndExamine) { |
| 240 std::vector<base::FilePath> returned_root_path( | 203 std::vector<base::FilePath> returned_root_path( |
| 241 ARRAYSIZE_UNSAFE(kRootPathTestCases)); | 204 ARRAYSIZE_UNSAFE(kRootPathTestCases)); |
| 242 SetUpNewBackend(CreateAllowFileAccessOptions()); | 205 SetUpNewBackend(CreateAllowFileAccessOptions()); |
| 243 | 206 |
| 244 // Create a new root directory. | 207 // Create a new root directory. |
| 245 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) { | 208 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) { |
| 246 SCOPED_TRACE(testing::Message() << "RootPath (create) #" << i << " " | 209 SCOPED_TRACE(testing::Message() << "RootPath (create) #" << i << " " |
| 247 << kRootPathTestCases[i].expected_path); | 210 << kRootPathTestCases[i].expected_path); |
| 248 | 211 |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 351 OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, | 314 OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT, |
| 352 &root_path)); | 315 &root_path)); |
| 353 base::FilePath expected = file_system_path().AppendASCII( | 316 base::FilePath expected = file_system_path().AppendASCII( |
| 354 kRootPathFileURITestCases[i].expected_path); | 317 kRootPathFileURITestCases[i].expected_path); |
| 355 EXPECT_EQ(expected.value(), root_path.value()); | 318 EXPECT_EQ(expected.value(), root_path.value()); |
| 356 EXPECT_TRUE(base::DirectoryExists(root_path)); | 319 EXPECT_TRUE(base::DirectoryExists(root_path)); |
| 357 } | 320 } |
| 358 } | 321 } |
| 359 | 322 |
| 360 } // namespace fileapi | 323 } // namespace fileapi |
| OLD | NEW |