summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi
diff options
context:
space:
mode:
authorericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-28 01:12:18 +0000
committerericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-05-28 01:12:18 +0000
commit054702d224472e01faf94482e2219ff1cd2b1aa7 (patch)
tree4e4a2074c84c7acf8a31ff40af9eb372b0037c0d /webkit/fileapi
parent1ebd7b1c556b39785a7e7fb80e959caf2e43fe93 (diff)
downloadchromium_src-054702d224472e01faf94482e2219ff1cd2b1aa7.zip
chromium_src-054702d224472e01faf94482e2219ff1cd2b1aa7.tar.gz
chromium_src-054702d224472e01faf94482e2219ff1cd2b1aa7.tar.bz2
Code to turn on obfuscated filesystems for all, and to migrate all existing users automatically whenever they next access the filesystem or check its quota usage.
Avi, I've added you just for the ChildProcessSecurity stuff in worker_process_host.cc and browser_render_process_host.cc. Drop me a line if you need to know what's going on there. This is for M13, so please ask soon. BUG=none TEST=unit tests Review URL: http://codereview.chromium.org/6976017 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@87129 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r--webkit/fileapi/file_system_dir_url_request_job_unittest.cc20
-rw-r--r--webkit/fileapi/file_system_file_util_unittest.cc53
-rw-r--r--webkit/fileapi/file_system_path_manager_unittest.cc50
-rw-r--r--webkit/fileapi/file_system_test_helper.cc31
-rw-r--r--webkit/fileapi/file_system_test_helper.h6
-rw-r--r--webkit/fileapi/file_system_url_request_job_unittest.cc48
-rw-r--r--webkit/fileapi/file_system_usage_cache.cc2
-rw-r--r--webkit/fileapi/file_system_util.cc4
-rw-r--r--webkit/fileapi/obfuscated_file_system_file_util.cc12
-rw-r--r--webkit/fileapi/quota_file_util_unittest.cc18
-rw-r--r--webkit/fileapi/sandbox_mount_point_provider.cc337
-rw-r--r--webkit/fileapi/sandbox_mount_point_provider.h48
-rw-r--r--webkit/fileapi/sandbox_mount_point_provider_unittest.cc344
13 files changed, 729 insertions, 244 deletions
diff --git a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
index a504f95..c4bb53e 100644
--- a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
+++ b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc
@@ -15,7 +15,6 @@
#include <string>
#include "base/file_path.h"
-#include "base/file_util.h"
#include "base/format_macros.h"
#include "base/message_loop.h"
#include "base/platform_file.h"
@@ -28,7 +27,10 @@
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_file_util.h"
+#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/sandbox_mount_point_provider.h"
namespace fileapi {
namespace {
@@ -122,8 +124,20 @@ class FileSystemDirURLRequestJobTest : public testing::Test {
}
void CreateDirectory(const base::StringPiece dir_name) {
- FilePath path = root_path_.AppendASCII(dir_name);
- ASSERT_TRUE(file_util::CreateDirectory(path));
+ FilePath path = FilePath().AppendASCII(dir_name);
+ FileSystemFileUtil* file_util = file_system_context_->path_manager()->
+ sandbox_provider()->GetFileSystemFileUtil();
+ FileSystemOperationContext context(file_system_context_, file_util);
+ context.set_src_origin_url(GURL("http://remote"));
+ context.set_src_virtual_path(path);
+ context.set_src_type(fileapi::kFileSystemTypeTemporary);
+ context.set_allowed_bytes_growth(1024);
+
+ ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateDirectory(
+ &context,
+ path,
+ false /* exclusive */,
+ false /* recursive */));
}
GURL CreateFileSystemURL(const std::string path) {
diff --git a/webkit/fileapi/file_system_file_util_unittest.cc b/webkit/fileapi/file_system_file_util_unittest.cc
index 056aa24..4203024 100644
--- a/webkit/fileapi/file_system_file_util_unittest.cc
+++ b/webkit/fileapi/file_system_file_util_unittest.cc
@@ -73,46 +73,37 @@ class FileSystemFileUtilTest : public testing::Test {
const GURL& src_origin, fileapi::FileSystemType src_type,
const GURL& dest_origin, fileapi::FileSystemType dest_type,
bool copy) {
- ScopedTempDir src_dir;
- ASSERT_TRUE(src_dir.CreateUniqueTempDir());
- scoped_refptr<ObfuscatedFileSystemFileUtil> src_util(
- new ObfuscatedFileSystemFileUtil(src_dir.path()));
+ ScopedTempDir base_dir;
+ ASSERT_TRUE(base_dir.CreateUniqueTempDir());
+ scoped_refptr<ObfuscatedFileSystemFileUtil> file_util(
+ new ObfuscatedFileSystemFileUtil(base_dir.path()));
FileSystemTestOriginHelper src_helper(src_origin, src_type);
- src_helper.SetUp(src_dir.path(),
- false, // incognito
- false, // unlimited quota
- NULL, // quota::QuotaManagerProxy
- src_util.get());
- ScopedTempDir dest_dir;
- ASSERT_TRUE(dest_dir.CreateUniqueTempDir());
- scoped_refptr<ObfuscatedFileSystemFileUtil> dest_util(
- new ObfuscatedFileSystemFileUtil(dest_dir.path()));
+ src_helper.SetUp(base_dir.path(),
+ false, // incognito
+ false, // unlimited quota
+ NULL, // quota::QuotaManagerProxy
+ file_util.get());
FileSystemTestOriginHelper dest_helper(dest_origin, dest_type);
- dest_helper.SetUp(dest_dir.path(),
- false, // incognito
- false, // unlimited quota
- NULL, // quota::QuotaManagerProxy
- dest_util.get());
+ dest_helper.SetUp(src_helper.file_system_context(), NULL);
// Set up all the source data.
scoped_ptr<FileSystemOperationContext> context;
FilePath test_root(FILE_PATH_LITERAL("root directory"));
for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "Creating kCopyMoveTestCases " << i);
const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
FilePath path = test_root.Append(test_case.path);
if (test_case.is_directory) {
context.reset(NewContext(&src_helper));
ASSERT_EQ(base::PLATFORM_FILE_OK,
- src_util->CreateDirectory(context.get(), path, true, true));
+ file_util->CreateDirectory(context.get(), path, true, true));
} else {
context.reset(NewContext(&src_helper));
bool created = false;
ASSERT_EQ(base::PLATFORM_FILE_OK,
- src_util->EnsureFileExists(context.get(), path, &created));
+ file_util->EnsureFileExists(context.get(), path, &created));
ASSERT_TRUE(created);
context.reset(NewContext(&src_helper));
- ASSERT_EQ(base::PLATFORM_FILE_OK, src_util->Truncate(
+ ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->Truncate(
context.get(), path, test_case.data_file_size));
}
}
@@ -121,8 +112,8 @@ class FileSystemFileUtilTest : public testing::Test {
FileSystemContext* file_system_context = dest_helper.file_system_context();
scoped_ptr<FileSystemOperationContext> copy_context(
new FileSystemOperationContext(file_system_context, NULL));
- copy_context->set_src_file_system_file_util(src_util);
- copy_context->set_dest_file_system_file_util(dest_util);
+ copy_context->set_src_file_system_file_util(file_util);
+ copy_context->set_dest_file_system_file_util(file_util);
copy_context->set_src_origin_url(src_helper.origin());
copy_context->set_dest_origin_url(dest_helper.origin());
copy_context->set_src_type(src_helper.type());
@@ -131,23 +122,21 @@ class FileSystemFileUtilTest : public testing::Test {
if (copy)
ASSERT_EQ(base::PLATFORM_FILE_OK,
- src_util->Copy(copy_context.get(), test_root, test_root));
+ file_util->Copy(copy_context.get(), test_root, test_root));
else
ASSERT_EQ(base::PLATFORM_FILE_OK,
- src_util->Move(copy_context.get(), test_root, test_root));
+ file_util->Move(copy_context.get(), test_root, test_root));
// Validate that the destination paths are correct.
for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "Validating kCopyMoveTestCases " << i);
const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
FilePath path = test_root.Append(test_case.path);
- SCOPED_TRACE(testing::Message() << "Path is " << test_case.path);
base::PlatformFileInfo dest_file_info;
FilePath data_path;
context.reset(NewContext(&dest_helper));
EXPECT_EQ(base::PLATFORM_FILE_OK,
- dest_util->GetFileInfo(
+ file_util->GetFileInfo(
context.get(), path, &dest_file_info, &data_path));
if (test_case.is_directory) {
EXPECT_TRUE(dest_file_info.is_directory);
@@ -164,12 +153,8 @@ class FileSystemFileUtilTest : public testing::Test {
// Validate that the source paths are still there [for a copy] or gone [for
// a move].
for (size_t i = 0; i < arraysize(kCopyMoveTestCases); ++i) {
- SCOPED_TRACE(testing::Message() << "Validating kCopyMoveTestCases " <<
- i);
const CopyMoveTestCaseRecord& test_case = kCopyMoveTestCases[i];
FilePath path = test_root.Append(test_case.path);
- SCOPED_TRACE(testing::Message() << "Path is " << test_case.path);
-
base::PlatformFileInfo src_file_info;
FilePath data_path;
context.reset(NewContext(&src_helper));
@@ -179,7 +164,7 @@ class FileSystemFileUtilTest : public testing::Test {
else
expected_result = base::PLATFORM_FILE_ERROR_NOT_FOUND;
EXPECT_EQ(expected_result,
- src_util->GetFileInfo(
+ file_util->GetFileInfo(
context.get(), path, &src_file_info, &data_path));
}
}
diff --git a/webkit/fileapi/file_system_path_manager_unittest.cc b/webkit/fileapi/file_system_path_manager_unittest.cc
index f1f9122..cfdd5ca 100644
--- a/webkit/fileapi/file_system_path_manager_unittest.cc
+++ b/webkit/fileapi/file_system_path_manager_unittest.cc
@@ -8,7 +8,6 @@
#include <string>
#include "base/basictypes.h"
-#include "base/command_line.h" // TODO(ericu): Remove this.
#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_callback_factory.h"
@@ -27,9 +26,6 @@
namespace fileapi {
namespace {
-// TODO(ericu): Remove this.
-static const char kObfuscationFlag[] = "use-obfuscated-file-system";
-
// PS stands for path separator.
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
#define PS "\\"
@@ -49,21 +45,21 @@ const struct RootPathTest {
const char* expected_path;
} kRootPathTestCases[] = {
{ fileapi::kFileSystemTypeTemporary, "http://foo:1/",
- "http_foo_1" PS "Temporary" },
+ "000" PS "t" },
{ fileapi::kFileSystemTypePersistent, "http://foo:1/",
- "http_foo_1" PS "Persistent" },
+ "000" PS "p" },
{ fileapi::kFileSystemTypeTemporary, "http://bar.com/",
- "http_bar.com_0" PS "Temporary" },
+ "001" PS "t" },
{ fileapi::kFileSystemTypePersistent, "http://bar.com/",
- "http_bar.com_0" PS "Persistent" },
+ "001" PS "p" },
{ fileapi::kFileSystemTypeTemporary, "https://foo:2/",
- "https_foo_2" PS "Temporary" },
+ "002" PS "t" },
{ fileapi::kFileSystemTypePersistent, "https://foo:2/",
- "https_foo_2" PS "Persistent" },
+ "002" PS "p" },
{ fileapi::kFileSystemTypeTemporary, "https://bar.com/",
- "https_bar.com_0" PS "Temporary" },
+ "003" PS "t" },
{ fileapi::kFileSystemTypePersistent, "https://bar.com/",
- "https_bar.com_0" PS "Persistent" },
+ "003" PS "p" },
#if defined(OS_CHROMEOS)
{ fileapi::kFileSystemTypeExternal, "chrome-extension://foo/",
"chrome-extension__0" PS "External" },
@@ -77,9 +73,9 @@ const struct RootPathFileURITest {
const char* virtual_path;
} kRootPathFileURITestCases[] = {
{ fileapi::kFileSystemTypeTemporary, "file:///",
- "file__0" PS "Temporary", NULL },
+ "000" PS "t", NULL },
{ fileapi::kFileSystemTypePersistent, "file:///",
- "file__0" PS "Persistent", NULL },
+ "000" PS "p", NULL },
#if defined(OS_CHROMEOS)
{ fileapi::kFileSystemTypeExternal, "chrome-extension://foo/",
"chrome-extension__0" PS "External", "testing" },
@@ -259,7 +255,7 @@ class FileSystemPathManagerTest : public testing::Test {
FilePath data_path() { return data_dir_.path(); }
FilePath file_system_path() {
return data_dir_.path().Append(
- SandboxMountPointProvider::kFileSystemDirectory);
+ SandboxMountPointProvider::kNewFileSystemDirectory);
}
FilePath external_file_system_path() {
return UTF8ToFilePath(std::string(fileapi::kExternalDir));
@@ -296,13 +292,9 @@ TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamine) {
true /* create */, &root_path));
if (kRootPathTestCases[i].type != fileapi::kFileSystemTypeExternal) {
- // TODO(ericu): Put this test back, with new expectations, when we've
- // switched over to the obfuscated filesystem.
- if (!CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag)) {
- FilePath expected = file_system_path().AppendASCII(
- kRootPathTestCases[i].expected_path);
- EXPECT_EQ(expected.value(), root_path.DirName().value());
- }
+ FilePath expected = file_system_path().AppendASCII(
+ kRootPathTestCases[i].expected_path);
+ EXPECT_EQ(expected.value(), root_path.value());
EXPECT_TRUE(file_util::DirectoryExists(root_path));
} else {
// External file system root path is virtual one and does not match
@@ -333,16 +325,17 @@ TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamine) {
TEST_F(FileSystemPathManagerTest, GetRootPathCreateAndExamineWithNewManager) {
std::vector<FilePath> returned_root_path(
ARRAYSIZE_UNSAFE(kRootPathTestCases));
- scoped_ptr<FileSystemPathManager> manager1(NewPathManager(false, false));
- scoped_ptr<FileSystemPathManager> manager2(NewPathManager(false, false));
+ scoped_ptr<FileSystemPathManager> manager(NewPathManager(false, false));
GURL origin_url("http://foo.com:1/");
FilePath root_path1;
- EXPECT_TRUE(GetRootPath(manager1.get(), origin_url,
+ EXPECT_TRUE(GetRootPath(manager.get(), origin_url,
kFileSystemTypeTemporary, true, &root_path1));
+
+ manager.reset(NewPathManager(false, false));
FilePath root_path2;
- EXPECT_TRUE(GetRootPath(manager2.get(), origin_url,
+ EXPECT_TRUE(GetRootPath(manager.get(), origin_url,
kFileSystemTypeTemporary, false, &root_path2));
EXPECT_EQ(root_path1.value(), root_path2.value());
@@ -403,10 +396,7 @@ TEST_F(FileSystemPathManagerTest, GetRootPathFileURIWithAllowFlag) {
if (kRootPathFileURITestCases[i].type != fileapi::kFileSystemTypeExternal) {
FilePath expected = file_system_path().AppendASCII(
kRootPathFileURITestCases[i].expected_path);
- // TODO(ericu): Put this test back, with new expectations, when we've
- // switched over to the obfuscated filesystem.
- if (!CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- EXPECT_EQ(expected.value(), root_path.DirName().value());
+ EXPECT_EQ(expected.value(), root_path.value());
EXPECT_TRUE(file_util::DirectoryExists(root_path));
} else {
EXPECT_EQ(external_file_path_root().value(), root_path.value());
diff --git a/webkit/fileapi/file_system_test_helper.cc b/webkit/fileapi/file_system_test_helper.cc
index bef48ba..c51fe7f 100644
--- a/webkit/fileapi/file_system_test_helper.cc
+++ b/webkit/fileapi/file_system_test_helper.cc
@@ -64,12 +64,37 @@ void FileSystemTestOriginHelper::SetUp(
}
void FileSystemTestOriginHelper::SetUp(
+ FileSystemContext* file_system_context,
+ FileSystemFileUtil* file_util) {
+ DCHECK(file_system_context->path_manager());
+ DCHECK(file_system_context->path_manager()->sandbox_provider());
+
+ file_util_ = file_util;
+ file_system_context_ = file_system_context;
+ if (!file_util_)
+ file_util_ = file_system_context->path_manager()->sandbox_provider()->
+ GetFileSystemFileUtil();
+ DCHECK(file_util_);
+
+ // Prepare the origin's root directory.
+ file_system_context_->path_manager()->
+ ValidateFileSystemRootAndGetPathOnFileThread(
+ origin_, type_, FilePath(), true /* create */);
+
+ // Initialize the usage cache file.
+ FilePath usage_cache_path = file_system_context_->path_manager()
+ ->sandbox_provider()->GetUsageCachePathForOriginAndType(origin_, type_);
+ FileSystemUsageCache::UpdateUsage(usage_cache_path, 0);
+}
+
+void FileSystemTestOriginHelper::SetUp(
const FilePath& base_dir,
bool incognito_mode,
bool unlimited_quota,
quota::QuotaManagerProxy* quota_manager_proxy,
FileSystemFileUtil* file_util) {
file_util_ = file_util ? file_util : LocalFileSystemFileUtil::GetInstance();
+ DCHECK(file_util_);
file_system_context_ = new FileSystemContext(
base::MessageLoopProxy::CreateForCurrentThread(),
base::MessageLoopProxy::CreateForCurrentThread(),
@@ -92,8 +117,7 @@ void FileSystemTestOriginHelper::SetUp(
// Initialize the usage cache file.
FilePath usage_cache_path = file_system_context_->path_manager()
->sandbox_provider()->GetUsageCachePathForOriginAndType(origin_, type_);
- FileSystemUsageCache::UpdateUsage(
- usage_cache_path, FileSystemUsageCache::kUsageFileSize);
+ FileSystemUsageCache::UpdateUsage(usage_cache_path, 0);
// We expect the origin directory to be always empty, except for possibly
// the usage cache file. We record the initial usage file size here
@@ -138,8 +162,7 @@ FilePath FileSystemTestOriginHelper::GetUsageCachePath() const {
}
int64 FileSystemTestOriginHelper::GetCachedOriginUsage() const {
- return FileSystemUsageCache::GetUsage(GetUsageCachePath()) -
- FileSystemUsageCache::kUsageFileSize;
+ return FileSystemUsageCache::GetUsage(GetUsageCachePath());
}
int64 FileSystemTestOriginHelper::ComputeCurrentOriginUsage() const {
diff --git a/webkit/fileapi/file_system_test_helper.h b/webkit/fileapi/file_system_test_helper.h
index c813cf7..5f8ab88 100644
--- a/webkit/fileapi/file_system_test_helper.h
+++ b/webkit/fileapi/file_system_test_helper.h
@@ -40,6 +40,12 @@ class FileSystemTestOriginHelper {
~FileSystemTestOriginHelper();
void SetUp(const FilePath& base_dir, FileSystemFileUtil* file_util);
+ // If you want to use more than one FileSystemTestOriginHelper in a single
+ // base directory, they have to share a context, so that they don't have
+ // multiple databases fighting over the lock to the origin directory [deep
+ // down inside ObfuscatedFileSystemFileUtil].
+ void SetUp(FileSystemContext* file_system_context,
+ FileSystemFileUtil* file_util);
void SetUp(const FilePath& base_dir,
bool incognito_mode,
bool unlimited_quota,
diff --git a/webkit/fileapi/file_system_url_request_job_unittest.cc b/webkit/fileapi/file_system_url_request_job_unittest.cc
index 0012c64..e7b91ec 100644
--- a/webkit/fileapi/file_system_url_request_job_unittest.cc
+++ b/webkit/fileapi/file_system_url_request_job_unittest.cc
@@ -32,7 +32,10 @@
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_file_util.h"
+#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/sandbox_mount_point_provider.h"
namespace fileapi {
namespace {
@@ -152,10 +155,47 @@ class FileSystemURLRequestJobTest : public testing::Test {
TestRequestHelper(url, NULL, false);
}
- void WriteFile(const base::StringPiece file_name,
+ void CreateDirectory(const base::StringPiece& dir_name) {
+ FilePath path = FilePath().AppendASCII(dir_name);
+ FileSystemFileUtil* file_util = file_system_context_->path_manager()->
+ sandbox_provider()->GetFileSystemFileUtil();
+ FileSystemOperationContext context(file_system_context_, file_util);
+ context.set_src_origin_url(GURL("http://remote"));
+ context.set_src_virtual_path(path);
+ context.set_src_type(fileapi::kFileSystemTypeTemporary);
+ context.set_allowed_bytes_growth(1024);
+
+ ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateDirectory(
+ &context,
+ path,
+ false /* exclusive */,
+ false /* recursive */));
+ }
+
+ void WriteFile(const base::StringPiece& file_name,
const char* buf, int buf_size) {
- FilePath path = origin_root_path_.AppendASCII(file_name);
- ASSERT_EQ(buf_size, file_util::WriteFile(path, buf, buf_size));
+ FilePath path = FilePath().AppendASCII(file_name);
+ FileSystemFileUtil* file_util = file_system_context_->path_manager()->
+ sandbox_provider()->GetFileSystemFileUtil();
+ FileSystemOperationContext context(file_system_context_, file_util);
+ context.set_src_origin_url(GURL("http://remote"));
+ context.set_src_virtual_path(path);
+ context.set_src_type(fileapi::kFileSystemTypeTemporary);
+ context.set_allowed_bytes_growth(1024);
+
+ base::PlatformFile handle = base::kInvalidPlatformFileValue;
+ bool created = false;
+ ASSERT_EQ(base::PLATFORM_FILE_OK, file_util->CreateOrOpen(
+ &context,
+ path,
+ base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_WRITE,
+ &handle,
+ &created));
+ EXPECT_TRUE(created);
+ ASSERT_NE(base::kInvalidPlatformFileValue, handle);
+ ASSERT_EQ(buf_size,
+ base::WritePlatformFile(handle, 0 /* offset */, buf, buf_size));
+ base::ClosePlatformFile(handle);
}
GURL CreateFileSystemURL(const std::string& path) {
@@ -271,7 +311,7 @@ TEST_F(FileSystemURLRequestJobTest, RangeOutOfBounds) {
}
TEST_F(FileSystemURLRequestJobTest, FileDirRedirect) {
- ASSERT_TRUE(file_util::CreateDirectory(origin_root_path_.AppendASCII("dir")));
+ CreateDirectory("dir");
TestRequest(CreateFileSystemURL("dir"));
EXPECT_EQ(1, delegate_->received_redirect_count());
diff --git a/webkit/fileapi/file_system_usage_cache.cc b/webkit/fileapi/file_system_usage_cache.cc
index 0445e72..b87620b 100644
--- a/webkit/fileapi/file_system_usage_cache.cc
+++ b/webkit/fileapi/file_system_usage_cache.cc
@@ -97,6 +97,7 @@ int64 FileSystemUsageCache::Read(const FilePath& usage_file_path,
uint32* dirty) {
char buffer[kUsageFileSize];
const char *header;
+ DCHECK(!usage_file_path.empty());
if (kUsageFileSize !=
file_util::ReadFile(usage_file_path, buffer, kUsageFileSize))
return -1;
@@ -126,6 +127,7 @@ int FileSystemUsageCache::Write(const FilePath& usage_file_path,
write_pickle.WriteUInt32(dirty);
write_pickle.WriteInt64(fs_usage);
+ DCHECK(!usage_file_path.empty());
FilePath temporary_usage_file_path;
file_util::CreateTemporaryFileInDir(usage_file_path.DirName(),
&temporary_usage_file_path);
diff --git a/webkit/fileapi/file_system_util.cc b/webkit/fileapi/file_system_util.cc
index 8435a76..80b22e4 100644
--- a/webkit/fileapi/file_system_util.cc
+++ b/webkit/fileapi/file_system_util.cc
@@ -103,9 +103,9 @@ bool CrackFileSystemURL(const GURL& url, GURL* origin_url, FileSystemType* type,
if (file_path)
#if defined(OS_WIN)
*file_path = FilePath(base::SysUTF8ToWide(path)).
- NormalizeWindowsPathSeparators();
+ NormalizeWindowsPathSeparators().StripTrailingSeparators();
#elif defined(OS_POSIX)
- *file_path = FilePath(path);
+ *file_path = FilePath(path).StripTrailingSeparators();
#endif
return true;
diff --git a/webkit/fileapi/obfuscated_file_system_file_util.cc b/webkit/fileapi/obfuscated_file_system_file_util.cc
index faaa8f6..c953bed 100644
--- a/webkit/fileapi/obfuscated_file_system_file_util.cc
+++ b/webkit/fileapi/obfuscated_file_system_file_util.cc
@@ -77,7 +77,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen(
if (!db->GetFileWithPath(virtual_path, &file_id)) {
// The file doesn't exist.
if (!(file_flags & (base::PLATFORM_FILE_CREATE |
- base::PLATFORM_FILE_CREATE_ALWAYS)))
+ base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_OPEN_ALWAYS)))
return base::PLATFORM_FILE_ERROR_NOT_FOUND;
FileId parent_id;
if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id))
@@ -878,7 +878,15 @@ bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox(
// TODO(ericu): Should we adjust the mtime of the root directory to match as
// well?
FilePath legacy_dest_dir = dest_root.Append(kLegacyDataDirectory);
- return file_util::Move(src_root, legacy_dest_dir);
+
+ if (!file_util::Move(src_root, legacy_dest_dir)) {
+ LOG(WARNING) <<
+ "The final step of a migration failed; I'll try to clean up.";
+ db = NULL;
+ DestroyDirectoryDatabase(origin_url, type);
+ return false;
+ }
+ return true;
}
// static
diff --git a/webkit/fileapi/quota_file_util_unittest.cc b/webkit/fileapi/quota_file_util_unittest.cc
index df59c70..72d0919 100644
--- a/webkit/fileapi/quota_file_util_unittest.cc
+++ b/webkit/fileapi/quota_file_util_unittest.cc
@@ -17,7 +17,7 @@
#include "webkit/fileapi/file_system_test_helper.h"
#include "webkit/fileapi/file_system_types.h"
#include "webkit/fileapi/file_system_usage_cache.h"
-#include "webkit/fileapi/local_file_system_file_util.h"
+#include "webkit/fileapi/obfuscated_file_system_file_util.h"
namespace fileapi {
@@ -29,16 +29,15 @@ class QuotaFileUtilTest : public testing::Test {
void SetUp() {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
- FilePath base_dir = data_dir_.path().AppendASCII("filesystem");
-
- // For path translation we rely on LocalFileSystemFileUtil::GetLocalPath().
- local_test_helper_.SetUp(base_dir, LocalFileSystemFileUtil::GetInstance());
- quota_test_helper_.SetUp(base_dir, QuotaFileUtil::GetInstance());
+ quota_test_helper_.SetUp(data_dir_.path(), QuotaFileUtil::GetInstance());
+ obfuscated_test_helper_.SetUp(
+ quota_test_helper_.file_system_context(), NULL);
+ base_dir_ = obfuscated_test_helper_.GetOriginRootPath();
}
void TearDown() {
- local_test_helper_.TearDown();
quota_test_helper_.TearDown();
+ obfuscated_test_helper_.TearDown();
}
protected:
@@ -47,7 +46,7 @@ class QuotaFileUtilTest : public testing::Test {
}
FilePath Path(const std::string& file_name) {
- return local_test_helper_.GetLocalPathFromASCII(file_name);
+ return base_dir_.AppendASCII(file_name);
}
base::PlatformFileError CreateFile(const char* file_name,
@@ -73,7 +72,8 @@ class QuotaFileUtilTest : public testing::Test {
private:
ScopedTempDir data_dir_;
- FileSystemTestOriginHelper local_test_helper_;
+ FilePath base_dir_;
+ FileSystemTestOriginHelper obfuscated_test_helper_;
FileSystemTestOriginHelper quota_test_helper_;
base::ScopedCallbackFactory<QuotaFileUtilTest> callback_factory_;
diff --git a/webkit/fileapi/sandbox_mount_point_provider.cc b/webkit/fileapi/sandbox_mount_point_provider.cc
index 0efd876..2c32d74 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.cc
+++ b/webkit/fileapi/sandbox_mount_point_provider.cc
@@ -29,13 +29,11 @@ using quota::QuotaManagerProxy;
namespace {
-static const char kObfuscationFlag[] = "use-obfuscated-file-system";
-
-static const FilePath::CharType kFileSystemUniqueNamePrefix[] =
+static const FilePath::CharType kOldFileSystemUniqueNamePrefix[] =
FILE_PATH_LITERAL("chrome-");
-static const int kFileSystemUniqueLength = 16;
-static const unsigned kFileSystemUniqueDirectoryNameLength =
- kFileSystemUniqueLength + arraysize(kFileSystemUniqueNamePrefix) - 1;
+static const int kOldFileSystemUniqueLength = 16;
+static const unsigned kOldFileSystemUniqueDirectoryNameLength =
+ kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1;
// Restricted names.
// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
@@ -59,57 +57,40 @@ inline std::string FilePathStringToASCII(
#endif
}
-FilePath::StringType CreateUniqueDirectoryName(const GURL& origin_url) {
+FilePath::StringType OldCreateUniqueDirectoryName(const GURL& origin_url) {
// This can be anything but need to be unpredictable.
static const FilePath::CharType letters[] = FILE_PATH_LITERAL(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
- FilePath::StringType unique(kFileSystemUniqueNamePrefix);
- for (int i = 0; i < kFileSystemUniqueLength; ++i)
+ FilePath::StringType unique(kOldFileSystemUniqueNamePrefix);
+ for (int i = 0; i < kOldFileSystemUniqueLength; ++i)
unique += letters[base::RandInt(0, arraysize(letters) - 2)];
return unique;
}
-bool ReadOriginDirectory(const FilePath& base_path,
- const GURL& origin_url,
- FilePath* unique) {
+base::PlatformFileError OldReadOriginDirectory(const FilePath& base_path,
+ FilePath* unique) {
file_util::FileEnumerator file_enum(
base_path, false /* recursive */,
file_util::FileEnumerator::DIRECTORIES,
- FilePath::StringType(kFileSystemUniqueNamePrefix) +
+ FilePath::StringType(kOldFileSystemUniqueNamePrefix) +
FILE_PATH_LITERAL("*"));
FilePath current;
bool found = false;
while (!(current = file_enum.Next()).empty()) {
if (current.BaseName().value().length() !=
- kFileSystemUniqueDirectoryNameLength)
+ kOldFileSystemUniqueDirectoryNameLength)
continue;
if (found) {
- // TODO(kinuko): Should notify the user to ask for some action.
LOG(WARNING) << "Unexpectedly found more than one FileSystem "
- << "directories for " << origin_url;
- return false;
+ << "directory";
+ return base::PLATFORM_FILE_ERROR_FAILED;
}
found = true;
*unique = current;
}
- return !unique->empty();
-}
-
-FilePath GetFileSystemRootPathOnFileThreadHelper(
- const GURL& origin_url, const FilePath& origin_base_path, bool create) {
- FilePath root;
- if (ReadOriginDirectory(origin_base_path, origin_url, &root))
- return root;
-
- if (!create)
- return FilePath();
-
- // Creates the root directory.
- root = origin_base_path.Append(CreateUniqueDirectoryName(origin_url));
- if (!file_util::CreateDirectory(root))
- return FilePath();
-
- return root;
+ if (unique->empty())
+ return base::PLATFORM_FILE_ERROR_NOT_FOUND;
+ return base::PLATFORM_FILE_OK;
}
class ObfuscatedOriginEnumerator
@@ -134,13 +115,13 @@ class ObfuscatedOriginEnumerator
enum_;
};
-class SandboxOriginEnumerator
+class OldSandboxOriginEnumerator
: public fileapi::SandboxMountPointProvider::OriginEnumerator {
public:
- explicit SandboxOriginEnumerator(const FilePath& base_path)
+ explicit OldSandboxOriginEnumerator(const FilePath& base_path)
: enumerator_(base_path, false /* recursive */,
file_util::FileEnumerator::DIRECTORIES) {}
- virtual ~SandboxOriginEnumerator() {}
+ virtual ~OldSandboxOriginEnumerator() {}
virtual GURL Next() OVERRIDE {
current_ = enumerator_.Next();
@@ -164,13 +145,132 @@ class SandboxOriginEnumerator
FilePath current_;
};
+FilePath OldGetBaseDirectoryForOrigin(
+ const FilePath& old_base_path,
+ const GURL& origin_url) {
+ std::string id = fileapi::GetOriginIdentifierFromURL(origin_url);
+ if (!id.empty())
+ return old_base_path.AppendASCII(id);
+ return FilePath();
+}
+
+FilePath OldGetBaseDirectoryForOriginAndType(
+ const FilePath& old_base_path,
+ const GURL& origin_url, fileapi::FileSystemType type) {
+ std::string type_string =
+ fileapi::FileSystemPathManager::GetFileSystemTypeString(type);
+ if (type_string.empty()) {
+ NOTREACHED();
+ return FilePath();
+ }
+ FilePath base_path = OldGetBaseDirectoryForOrigin(
+ old_base_path, origin_url);
+ if (base_path.empty()) {
+ NOTREACHED();
+ return FilePath();
+ }
+ return base_path.AppendASCII(type_string);
+}
+
+bool MigrateOneOldFileSystem(
+ fileapi::ObfuscatedFileSystemFileUtil* file_util,
+ const FilePath& old_base_path, const GURL& origin,
+ fileapi::FileSystemType type) {
+ FilePath base_path = OldGetBaseDirectoryForOriginAndType(
+ old_base_path, origin, type);
+ if (base_path.empty())
+ return false;
+
+ FilePath root;
+ base::PlatformFileError result = OldReadOriginDirectory(base_path, &root);
+ if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result)
+ return true; // There was nothing to migrate; call that a success.
+
+ // If we found more than one filesystem [a problem we don't know how to
+ // solve], the data is already not accessible through Chrome, so it won't do
+ // any harm not to migrate it. Just flag it as an error, so that we don't
+ // delete it.
+ if (base::PLATFORM_FILE_OK != result)
+ return false;
+
+ if (!file_util->MigrateFromOldSandbox(origin, type, root)) {
+ LOG(WARNING) << "Failed to migrate filesystem for origin " << origin <<
+ " and type " << type;
+ return false;
+ }
+ return true;
+}
+
+void MigrateAllOldFileSystems(
+ fileapi::ObfuscatedFileSystemFileUtil* file_util,
+ const FilePath& old_base_path) {
+ scoped_ptr<OldSandboxOriginEnumerator> old_origins(
+ new OldSandboxOriginEnumerator(old_base_path));
+ GURL origin;
+ int failures = 0;
+ while (!(origin = old_origins->Next()).is_empty()) {
+ int failures_this_origin = 0;
+ if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) &&
+ !MigrateOneOldFileSystem(
+ file_util, old_base_path, origin,
+ fileapi::kFileSystemTypeTemporary))
+ ++failures_this_origin;
+ if (old_origins->HasFileSystemType(fileapi::kFileSystemTypePersistent) &&
+ !MigrateOneOldFileSystem(
+ file_util, old_base_path, origin,
+ fileapi::kFileSystemTypePersistent))
+ ++failures_this_origin;
+ if (!failures_this_origin) {
+ FilePath origin_base_path =
+ OldGetBaseDirectoryForOrigin(old_base_path, origin);
+ // Yes, that's an rm -rf. Make sure that path looks valid, just in case.
+ if (!origin_base_path.empty())
+ file_util::Delete(origin_base_path, true);
+ }
+ failures += failures_this_origin;
+ }
+ if (!failures)
+ file_util::Delete(old_base_path, true);
+ if (file_util::DirectoryExists(old_base_path)) {
+ // Move it out of the way so that we won't keep trying to migrate it. You
+ // get only one chance at this; the bits we couldn't do this time, we're
+ // unlikely to be able to do in the future. This way you can now use the
+ // new filesystem, but have a way to recover your old files if absolutely
+ // necessary.
+ FilePath new_path =
+ old_base_path.DirName().Append(
+ fileapi::SandboxMountPointProvider::kRenamedOldFileSystemDirectory);
+ file_util::ReplaceFile(old_base_path, new_path);
+ }
+}
+
+// A migration, whether successful or not, will try to move this directory out
+// of the way so that we never try to migrate it again. We need to do this
+// check on all public entry points in this file, so that it's guaranteed to be
+// done before anyone looks up a filesystem. Most entry points start by trying
+// to look up the filesystem's root, so we can take care of most of them by
+// putting a check there.
+void MigrateIfNeeded(
+ fileapi::ObfuscatedFileSystemFileUtil* file_util,
+ const FilePath& old_base_path) {
+ if (file_util::DirectoryExists(old_base_path))
+ MigrateAllOldFileSystems(file_util, old_base_path);
+}
+
} // anonymous namespace
namespace fileapi {
-const FilePath::CharType SandboxMountPointProvider::kFileSystemDirectory[] =
+const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] =
FILE_PATH_LITERAL("FileSystem");
+const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] =
+ FILE_PATH_LITERAL("File System");
+
+const FilePath::CharType
+ SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] =
+ FILE_PATH_LITERAL("FS.old");
+
SandboxMountPointProvider::SandboxMountPointProvider(
FileSystemPathManager* path_manager,
scoped_refptr<base::MessageLoopProxy> file_message_loop,
@@ -178,8 +278,10 @@ SandboxMountPointProvider::SandboxMountPointProvider(
: FileSystemQuotaUtil(file_message_loop),
path_manager_(path_manager),
file_message_loop_(file_message_loop),
- base_path_(profile_path.Append(kFileSystemDirectory)),
- sandbox_file_util_(new ObfuscatedFileSystemFileUtil(base_path_)) {
+ profile_path_(profile_path),
+ sandbox_file_util_(
+ new ObfuscatedFileSystemFileUtil(
+ profile_path.Append(kNewFileSystemDirectory))) {
}
SandboxMountPointProvider::~SandboxMountPointProvider() {
@@ -203,35 +305,37 @@ class SandboxMountPointProvider::GetFileSystemRootPathTask
GetFileSystemRootPathTask(
scoped_refptr<base::MessageLoopProxy> file_message_loop,
const GURL& origin_url,
- const FilePath& origin_base_path,
FileSystemType type,
ObfuscatedFileSystemFileUtil* file_util,
+ const FilePath& old_base_path,
FileSystemPathManager::GetRootPathCallback* callback)
: file_message_loop_(file_message_loop),
origin_message_loop_proxy_(
base::MessageLoopProxy::CreateForCurrentThread()),
origin_url_(origin_url),
- origin_base_path_(origin_base_path),
type_(type),
file_util_(file_util),
+ old_base_path_(old_base_path),
callback_(callback) {
}
+ virtual ~GetFileSystemRootPathTask() {
+ // Just in case we get deleted without running, make sure to clean up the
+ // file_util_ on the right thread.
+ if (file_util_.get() && !file_message_loop_->BelongsToCurrentThread())
+ file_message_loop_->ReleaseSoon(FROM_HERE, file_util_.release());
+ }
+
void Start(bool create) {
file_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
&GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread, create));
}
private:
- void GetFileSystemRootPathOnFileThread(
- bool create) {
- if (file_util_.get())
- DispatchCallbackOnCallerThread(
- file_util_->GetDirectoryForOriginAndType(origin_url_, type_, create));
- else
- DispatchCallbackOnCallerThread(
- GetFileSystemRootPathOnFileThreadHelper(
- origin_url_, origin_base_path_, create));
+ void GetFileSystemRootPathOnFileThread(bool create) {
+ MigrateIfNeeded(file_util_, old_base_path_);
+ DispatchCallbackOnCallerThread(
+ file_util_->GetDirectoryForOriginAndType(origin_url_, type_, create));
// We must clear the reference on the file thread.
file_util_ = NULL;
}
@@ -255,12 +359,24 @@ class SandboxMountPointProvider::GetFileSystemRootPathTask
scoped_refptr<base::MessageLoopProxy> file_message_loop_;
scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
GURL origin_url_;
- FilePath origin_base_path_;
FileSystemType type_;
scoped_refptr<ObfuscatedFileSystemFileUtil> file_util_;
+ FilePath old_base_path_;
scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_;
};
+FilePath SandboxMountPointProvider::old_base_path() const {
+ return profile_path_.Append(kOldFileSystemDirectory);
+}
+
+FilePath SandboxMountPointProvider::new_base_path() const {
+ return profile_path_.Append(kNewFileSystemDirectory);
+}
+
+FilePath SandboxMountPointProvider::renamed_old_base_path() const {
+ return profile_path_.Append(kRenamedOldFileSystemDirectory);
+}
+
bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename)
const {
if (filename.value().empty())
@@ -295,22 +411,20 @@ std::vector<FilePath> SandboxMountPointProvider::GetRootDirectories() const {
NOTREACHED();
// TODO(ericu): Implement this method and check for access permissions as
// fileBrowserPrivate extension API does. We currently have another mechanism,
- // but we should switch over.
+ // but we should switch over. This may also need to call MigrateIfNeeded().
return std::vector<FilePath>();
}
SandboxMountPointProvider::OriginEnumerator*
SandboxMountPointProvider::CreateOriginEnumerator() const {
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- return new ObfuscatedOriginEnumerator(sandbox_file_util_.get());
- return new SandboxOriginEnumerator(base_path_);
+ MigrateIfNeeded(sandbox_file_util_, old_base_path());
+ return new ObfuscatedOriginEnumerator(sandbox_file_util_.get());
}
void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
const GURL& origin_url, fileapi::FileSystemType type,
bool create, FileSystemPathManager::GetRootPathCallback* callback_ptr) {
scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback(callback_ptr);
- ObfuscatedFileSystemFileUtil* file_util = NULL;
FilePath origin_base_path;
if (path_manager_->is_incognito()) {
@@ -324,22 +438,12 @@ void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
return;
}
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag)) {
- file_util = sandbox_file_util_.get();
- } else {
- std::string name;
- if (!GetOriginBasePathAndName(origin_url, &origin_base_path, type, &name)) {
- callback->Run(false, FilePath(), std::string());
- return;
- }
- }
-
scoped_refptr<GetFileSystemRootPathTask> task(
new GetFileSystemRootPathTask(file_message_loop_,
origin_url,
- origin_base_path,
type,
- file_util,
+ sandbox_file_util_.get(),
+ old_base_path(),
callback.release()));
task->Start(create);
};
@@ -355,40 +459,27 @@ SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread(
if (!path_manager_->IsAllowedScheme(origin_url))
return FilePath();
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- return sandbox_file_util_->GetDirectoryForOriginAndType(
- origin_url, type, create);
+ MigrateIfNeeded(sandbox_file_util_, old_base_path());
- std::string name;
- FilePath origin_base_path;
- if (!GetOriginBasePathAndName(origin_url, &origin_base_path, type, &name))
- return FilePath();
-
- return GetFileSystemRootPathOnFileThreadHelper(
- origin_url, origin_base_path, create);
+ return sandbox_file_util_->GetDirectoryForOriginAndType(
+ origin_url, type, create);
}
FilePath SandboxMountPointProvider::GetBaseDirectoryForOrigin(
const GURL& origin_url, bool create) const {
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- return sandbox_file_util_->GetDirectoryForOrigin(
- origin_url, create);
- return base_path_.AppendASCII(GetOriginIdentifierFromURL(origin_url));
+
+ MigrateIfNeeded(sandbox_file_util_, old_base_path());
+
+ return sandbox_file_util_->GetDirectoryForOrigin(origin_url, create);
}
-// Needed for the old way of doing things.
FilePath SandboxMountPointProvider::GetBaseDirectoryForOriginAndType(
const GURL& origin_url, fileapi::FileSystemType type, bool create) const {
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- return sandbox_file_util_->GetDirectoryForOriginAndType(
+
+ MigrateIfNeeded(sandbox_file_util_, old_base_path());
+
+ return sandbox_file_util_->GetDirectoryForOriginAndType(
origin_url, type, create);
- std::string type_string =
- FileSystemPathManager::GetFileSystemTypeString(type);
- if (type_string.empty()) {
- LOG(WARNING) << "Unknown filesystem type is requested:" << type;
- return FilePath();
- }
- return GetBaseDirectoryForOrigin(origin_url, create).AppendASCII(type_string);
}
bool SandboxMountPointProvider::DeleteOriginDataOnFileThread(
@@ -445,11 +536,11 @@ int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
type == fileapi::kFileSystemTypePersistent);
FilePath base_path =
GetBaseDirectoryForOriginAndType(origin_url, type, false);
- if (!file_util::DirectoryExists(base_path))
+ if (base_path.empty() || !file_util::DirectoryExists(base_path))
return 0;
+ FilePath usage_file_path =
+ base_path.AppendASCII(FileSystemUsageCache::kUsageFileName);
- FilePath usage_file_path = base_path.AppendASCII(
- FileSystemUsageCache::kUsageFileName);
int32 dirty_status = FileSystemUsageCache::GetDirty(usage_file_path);
bool visited = (visited_origins_.find(origin_url) != visited_origins_.end());
visited_origins_.insert(origin_url);
@@ -490,6 +581,7 @@ void SandboxMountPointProvider::UpdateOriginUsageOnFileThread(
type == fileapi::kFileSystemTypePersistent);
FilePath usage_file_path = GetUsageCachePathForOriginAndType(
origin_url, type);
+ DCHECK(!usage_file_path.empty());
FileSystemUsageCache::AtomicUpdateUsageByDelta(usage_file_path, delta);
if (proxy) {
proxy->NotifyStorageModified(
@@ -519,36 +611,41 @@ void SandboxMountPointProvider::EndUpdateOriginOnFileThread(
}
FileSystemFileUtil* SandboxMountPointProvider::GetFileSystemFileUtil() {
- if (CommandLine::ForCurrentProcess()->HasSwitch(kObfuscationFlag))
- return sandbox_file_util_.get();
- return LocalFileSystemFileUtil::GetInstance();
-}
-
-// Needed for the old way of doing things.
-bool SandboxMountPointProvider::GetOriginBasePathAndName(
- const GURL& origin_url,
- FilePath* origin_base_path,
- FileSystemType type,
- std::string* name) {
-
- *origin_base_path = GetBaseDirectoryForOriginAndType(origin_url, type, false);
- if (origin_base_path->empty())
- return false;
-
- std::string origin_identifier = GetOriginIdentifierFromURL(origin_url);
- std::string type_string =
- FileSystemPathManager::GetFileSystemTypeString(type);
- DCHECK(!type_string.empty());
- if (name)
- *name = origin_identifier + ":" + type_string;
- return true;
+ return sandbox_file_util_.get();
}
FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
const GURL& origin_url, fileapi::FileSystemType type) const {
FilePath base_path =
GetBaseDirectoryForOriginAndType(origin_url, type, false);
+ if (base_path.empty())
+ return FilePath();
return base_path.AppendASCII(FileSystemUsageCache::kUsageFileName);
}
+FilePath SandboxMountPointProvider::OldCreateFileSystemRootPath(
+ const GURL& origin_url, fileapi::FileSystemType type) {
+ FilePath origin_base_path =
+ OldGetBaseDirectoryForOriginAndType(old_base_path(), origin_url, type);
+ DCHECK(!origin_base_path.empty());
+
+ FilePath root;
+ base::PlatformFileError result =
+ OldReadOriginDirectory(origin_base_path, &root);
+ if (base::PLATFORM_FILE_OK == result)
+ return root;
+
+ // We found more than on filesystem there already--we don't know how to
+ // recover from this.
+ if (base::PLATFORM_FILE_ERROR_NOT_FOUND != result)
+ return FilePath();
+
+ // Creates the root directory.
+ root = origin_base_path.Append(OldCreateUniqueDirectoryName(origin_url));
+ if (!file_util::CreateDirectory(root))
+ return FilePath();
+
+ return root;
+}
+
} // namespace fileapi
diff --git a/webkit/fileapi/sandbox_mount_point_provider.h b/webkit/fileapi/sandbox_mount_point_provider.h
index 417aff8..6ea001b 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.h
+++ b/webkit/fileapi/sandbox_mount_point_provider.h
@@ -76,12 +76,17 @@ class SandboxMountPointProvider
const FilePath& unused,
bool create);
+ // The legacy [pre-obfuscation] FileSystem directory name, kept around for
+ // migration and migration testing.
+ static const FilePath::CharType kOldFileSystemDirectory[];
// The FileSystem directory name.
- static const FilePath::CharType kFileSystemDirectory[];
+ static const FilePath::CharType kNewFileSystemDirectory[];
+ // Where we move the old filesystem directory if migration fails.
+ static const FilePath::CharType kRenamedOldFileSystemDirectory[];
- const FilePath& base_path() const {
- return base_path_;
- }
+ FilePath old_base_path() const;
+ FilePath new_base_path() const;
+ FilePath renamed_old_base_path() const;
// Checks if a given |name| contains any restricted names/chars in it.
virtual bool IsRestrictedFileName(const FilePath& filename) const;
@@ -89,7 +94,7 @@ class SandboxMountPointProvider
virtual std::vector<FilePath> GetRootDirectories() const;
// Returns an origin enumerator of this provider.
- // This method is supposed to be called on the file thread.
+ // This method can only be called on the file thread.
OriginEnumerator* CreateOriginEnumerator() const;
// Gets a base directory path of the sandboxed filesystem that is
@@ -107,7 +112,7 @@ class SandboxMountPointProvider
// This method can only be called on the file thread.
FilePath GetBaseDirectoryForOriginAndType(
const GURL& origin_url,
- fileapi::FileSystemType type,
+ FileSystemType type,
bool create) const;
FileSystemFileUtil* GetFileSystemFileUtil();
@@ -117,52 +122,51 @@ class SandboxMountPointProvider
bool DeleteOriginDataOnFileThread(
quota::QuotaManagerProxy* proxy,
const GURL& origin_url,
- fileapi::FileSystemType type);
+ FileSystemType type);
// Quota util methods.
virtual void GetOriginsForTypeOnFileThread(
- fileapi::FileSystemType type,
+ FileSystemType type,
std::set<GURL>* origins) OVERRIDE;
virtual void GetOriginsForHostOnFileThread(
- fileapi::FileSystemType type,
+ FileSystemType type,
const std::string& host,
std::set<GURL>* origins) OVERRIDE;
virtual int64 GetOriginUsageOnFileThread(
const GURL& origin_url,
- fileapi::FileSystemType type) OVERRIDE;
+ FileSystemType type) OVERRIDE;
virtual void NotifyOriginWasAccessedOnIOThread(
quota::QuotaManagerProxy* proxy,
const GURL& origin_url,
- fileapi::FileSystemType type) OVERRIDE;
+ FileSystemType type) OVERRIDE;
virtual void UpdateOriginUsageOnFileThread(
quota::QuotaManagerProxy* proxy,
const GURL& origin_url,
- fileapi::FileSystemType type,
+ FileSystemType type,
int64 delta) OVERRIDE;
virtual void StartUpdateOriginOnFileThread(
const GURL& origin_url,
- fileapi::FileSystemType type) OVERRIDE;
+ FileSystemType type) OVERRIDE;
virtual void EndUpdateOriginOnFileThread(
const GURL& origin_url,
- fileapi::FileSystemType type) OVERRIDE;
+ FileSystemType type) OVERRIDE;
FileSystemQuotaUtil* quota_util() { return this; }
private:
- bool GetOriginBasePathAndName(
- const GURL& origin_url,
- FilePath* base_path,
- FileSystemType type,
- std::string* name);
-
// Returns a path to the usage cache file.
FilePath GetUsageCachePathForOriginAndType(
const GURL& origin_url,
- fileapi::FileSystemType type) const;
+ FileSystemType type) const;
+
+ FilePath OldCreateFileSystemRootPath(
+ const GURL& origin_url, FileSystemType type);
class GetFileSystemRootPathTask;
friend class FileSystemTestOriginHelper;
+ friend class SandboxMountPointProviderMigrationTest;
+ friend class SandboxMountPointProviderOriginEnumeratorTest;
// The path_manager_ isn't owned by this instance; this instance is owned by
// the path_manager_, and they have the same lifetime.
@@ -170,7 +174,7 @@ class SandboxMountPointProvider
scoped_refptr<base::MessageLoopProxy> file_message_loop_;
- const FilePath base_path_;
+ const FilePath profile_path_;
scoped_refptr<ObfuscatedFileSystemFileUtil> sandbox_file_util_;
diff --git a/webkit/fileapi/sandbox_mount_point_provider_unittest.cc b/webkit/fileapi/sandbox_mount_point_provider_unittest.cc
index d657715..2af14a5 100644
--- a/webkit/fileapi/sandbox_mount_point_provider_unittest.cc
+++ b/webkit/fileapi/sandbox_mount_point_provider_unittest.cc
@@ -14,9 +14,12 @@
#include "base/memory/scoped_ptr.h"
#include "base/message_loop.h"
#include "base/message_loop_proxy.h"
+#include "base/platform_file.h"
#include "base/scoped_temp_dir.h"
#include "googleurl/src/gurl.h"
#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_path_manager.h"
#include "webkit/fileapi/file_system_util.h"
@@ -24,9 +27,9 @@ namespace fileapi {
class MockFileSystemPathManager : public FileSystemPathManager {
public:
- MockFileSystemPathManager(const FilePath& filesystem_path)
+ MockFileSystemPathManager(const FilePath& profile_path)
: FileSystemPathManager(base::MessageLoopProxy::CreateForCurrentThread(),
- filesystem_path, NULL, false, true) {}
+ profile_path, NULL, false, true) {}
};
class SandboxMountPointProviderOriginEnumeratorTest : public testing::Test {
@@ -34,12 +37,10 @@ class SandboxMountPointProviderOriginEnumeratorTest : public testing::Test {
void SetUp() {
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
path_manager_.reset(new MockFileSystemPathManager(data_dir_.path()));
- enumerator_.reset(
- path_manager_->sandbox_provider()->CreateOriginEnumerator());
}
- SandboxMountPointProvider::OriginEnumerator* enumerator() const {
- return enumerator_.get();
+ SandboxMountPointProvider::OriginEnumerator* CreateEnumerator() const {
+ return path_manager_->sandbox_provider()->CreateOriginEnumerator();
}
protected:
@@ -47,17 +48,18 @@ class SandboxMountPointProviderOriginEnumeratorTest : public testing::Test {
fileapi::FileSystemType type) {
FilePath target = path_manager_->sandbox_provider()->
GetBaseDirectoryForOriginAndType(origin, type, true);
- file_util::CreateDirectory(target);
+ ASSERT_TRUE(!target.empty());
ASSERT_TRUE(file_util::DirectoryExists(target));
}
ScopedTempDir data_dir_;
scoped_ptr<FileSystemPathManager> path_manager_;
- scoped_ptr<SandboxMountPointProvider::OriginEnumerator> enumerator_;
};
TEST_F(SandboxMountPointProviderOriginEnumeratorTest, Empty) {
- ASSERT_TRUE(enumerator()->Next().is_empty());
+ scoped_ptr<SandboxMountPointProvider::OriginEnumerator> enumerator(
+ CreateEnumerator());
+ ASSERT_TRUE(enumerator->Next().is_empty());
}
TEST_F(SandboxMountPointProviderOriginEnumeratorTest, EnumerateOrigins) {
@@ -87,23 +89,337 @@ TEST_F(SandboxMountPointProviderOriginEnumeratorTest, EnumerateOrigins) {
persistent_set.insert(GURL(persistent_origins[i]));
}
+ scoped_ptr<SandboxMountPointProvider::OriginEnumerator> enumerator(
+ CreateEnumerator());
size_t temporary_actual_size = 0;
size_t persistent_actual_size = 0;
GURL current;
- while (!(current = enumerator()->Next()).is_empty()) {
+ while (!(current = enumerator->Next()).is_empty()) {
SCOPED_TRACE(testing::Message() << "EnumerateOrigin " << current.spec());
- if (enumerator()->HasFileSystemType(kFileSystemTypeTemporary)) {
+ if (enumerator->HasFileSystemType(kFileSystemTypeTemporary)) {
ASSERT_TRUE(temporary_set.find(current) != temporary_set.end());
++temporary_actual_size;
}
- if (enumerator()->HasFileSystemType(kFileSystemTypePersistent)) {
+ if (enumerator->HasFileSystemType(kFileSystemTypePersistent)) {
ASSERT_TRUE(persistent_set.find(current) != persistent_set.end());
++persistent_actual_size;
}
}
- ASSERT_EQ(temporary_size, temporary_actual_size);
- ASSERT_EQ(persistent_size, persistent_actual_size);
+ EXPECT_EQ(temporary_size, temporary_actual_size);
+ EXPECT_EQ(persistent_size, persistent_actual_size);
+}
+
+namespace {
+
+struct MigrationTestCaseRecord {
+ GURL origin;
+ bool has_temporary;
+ bool has_persistent;
+};
+
+const MigrationTestCaseRecord kMigrationTestRecords[] = {
+ { GURL("http://www.example.com"), true, false },
+ { GURL("http://example.com"), false, true },
+ { GURL("http://www.google.com"), false, true },
+ { GURL("http://www.another.origin.com"), true, true },
+ { GURL("http://www.yet.another.origin.com"), true, true },
+ { GURL("file:///"), false, true },
+};
+
+class TestSpecialStoragePolicy : public quota::SpecialStoragePolicy {
+ public:
+ TestSpecialStoragePolicy(bool unlimited_quota)
+ : unlimited_quota_(unlimited_quota) {}
+
+ virtual bool IsStorageProtected(const GURL& origin) {
+ return false;
+ }
+
+ virtual bool IsStorageUnlimited(const GURL& origin) {
+ return unlimited_quota_;
+ }
+
+ virtual bool IsFileHandler(const std::string& extension_id) {
+ return true;
+ }
+
+ private:
+ bool unlimited_quota_;
+};
+
+} // anonymous namespace
+
+class SandboxMountPointProviderMigrationTest : public testing::Test {
+ public:
+ SandboxMountPointProviderMigrationTest() :
+ ALLOW_THIS_IN_INITIALIZER_LIST(callback_factory_(this)) {
+ }
+
+ void SetUp() {
+ ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
+ path_manager_ = new MockFileSystemPathManager(data_dir_.path());
+
+ file_system_context_ = new FileSystemContext(
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ base::MessageLoopProxy::CreateForCurrentThread(),
+ new TestSpecialStoragePolicy(true /* unlimited quota */),
+ NULL,
+ data_dir_.path(),
+ false, // incognito
+ true, // allow_file_access_from_files
+ true, // unlimited quota
+ path_manager_);
+ }
+
+ FileSystemPathManager* path_manager() {
+ return path_manager_;
+ }
+
+ SandboxMountPointProvider* sandbox_provider() {
+ return path_manager()->sandbox_provider();
+ }
+
+ FileSystemFileUtil* file_util() {
+ return sandbox_provider()->GetFileSystemFileUtil();
+ }
+
+ void OnGetRootPath(bool success, const FilePath& unused,
+ const std::string& unused_also) {
+ EXPECT_FALSE(success); // We told it not to create.
+ }
+
+ FileSystemPathManager::GetRootPathCallback* GetRootPathCallback() {
+ return callback_factory_.NewCallback(
+ &SandboxMountPointProviderMigrationTest::OnGetRootPath);
+ }
+
+ void EnsureFileExists(const FilePath& path) {
+ bool created = false;
+ PlatformFileError error_code = base::PLATFORM_FILE_OK;
+ PlatformFile handle = base::CreatePlatformFile(
+ path,
+ base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_READ,
+ &created, &error_code);
+ ASSERT_EQ(base::PLATFORM_FILE_OK, error_code);
+ ASSERT_TRUE(created);
+ ASSERT_NE(base::kInvalidPlatformFileValue, handle);
+ base::ClosePlatformFile(handle);
+ }
+
+ void CreateDataInDir(const FilePath& root, const std::string& seed) {
+ ASSERT_TRUE(file_util::CreateDirectory(
+ root.AppendASCII(seed)));
+ ASSERT_TRUE(file_util::CreateDirectory(
+ root.AppendASCII(seed).AppendASCII(seed)));
+ ASSERT_TRUE(file_util::CreateDirectory(
+ root.AppendASCII(seed).AppendASCII("d 0")));
+ ASSERT_TRUE(file_util::CreateDirectory(
+ root.AppendASCII(seed).AppendASCII("d 1")));
+ EnsureFileExists(root.AppendASCII("file 0"));
+ EnsureFileExists(
+ root.AppendASCII(seed).AppendASCII("d 0").AppendASCII("file 1"));
+ EnsureFileExists(
+ root.AppendASCII(seed).AppendASCII("d 0").AppendASCII("file 2"));
+ }
+
+ FileSystemOperationContext* NewContext(const GURL& origin_url,
+ fileapi::FileSystemType type) {
+ FileSystemOperationContext* context = new FileSystemOperationContext(
+ file_system_context_, file_util());
+ context->set_src_origin_url(origin_url);
+ context->set_src_type(type);
+ return context;
+ }
+
+ std::string URLAndTypeToSeedString(const GURL& origin_url,
+ fileapi::FileSystemType type) {
+ return GetOriginIdentifierFromURL(origin_url) +
+ FileSystemPathManager::GetFileSystemTypeString(type);
+ }
+
+ void ValidateDataInNewFileSystem(
+ const GURL& origin_url, fileapi::FileSystemType type) {
+
+ scoped_ptr<FileSystemOperationContext> context;
+ FilePath seed = FilePath().AppendASCII(
+ URLAndTypeToSeedString(origin_url, type));
+
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->DirectoryExists(
+ context.get(), seed));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->DirectoryExists(
+ context.get(), seed.Append(seed)));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->DirectoryExists(
+ context.get(), seed.AppendASCII("d 0")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->DirectoryExists(
+ context.get(), seed.AppendASCII("d 1")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->PathExists(
+ context.get(), FilePath().AppendASCII("file 0")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_FALSE(file_util()->DirectoryExists(
+ context.get(), seed.AppendASCII("file 0")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->PathExists(
+ context.get(), seed.AppendASCII("d 0").AppendASCII("file 1")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_FALSE(file_util()->DirectoryExists(
+ context.get(), seed.AppendASCII("d 0").AppendASCII("file 1")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_TRUE(file_util()->PathExists(
+ context.get(), seed.AppendASCII("d 0").AppendASCII("file 2")));
+ context.reset(NewContext(origin_url, type));
+ EXPECT_FALSE(file_util()->DirectoryExists(
+ context.get(), seed.AppendASCII("d 0").AppendASCII("file 2")));
+ }
+
+ void RunMigrationTest(int method) {
+ for (size_t i = 0; i < arraysize(kMigrationTestRecords); ++i) {
+ const MigrationTestCaseRecord& test_case = kMigrationTestRecords[i];
+ const GURL& origin_url = test_case.origin;
+ ASSERT_TRUE(test_case.has_temporary || test_case.has_persistent);
+ if (test_case.has_temporary) {
+ FilePath root = sandbox_provider()->OldCreateFileSystemRootPath(
+ origin_url, kFileSystemTypeTemporary);
+ ASSERT_FALSE(root.empty());
+ CreateDataInDir(root, URLAndTypeToSeedString(origin_url,
+ kFileSystemTypeTemporary));
+ }
+ if (test_case.has_persistent) {
+ FilePath root = sandbox_provider()->OldCreateFileSystemRootPath(
+ origin_url, kFileSystemTypePersistent);
+ ASSERT_FALSE(root.empty());
+ CreateDataInDir(root, URLAndTypeToSeedString(origin_url,
+ kFileSystemTypePersistent));
+ }
+ }
+
+ const GURL origin_url("http://not.in.the.test.cases");
+ fileapi::FileSystemType type = kFileSystemTypeTemporary;
+ bool create = false;
+ std::set<GURL> origins;
+ std::string host = "the host with the most";
+ int64 delta = 0;
+ scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback;
+
+ // We want to make sure that all the public methods of
+ // SandboxMountPointProvider which might access the filesystem will cause a
+ // migration if one is needed.
+ switch (method) {
+ case 0:
+ callback.reset(GetRootPathCallback());
+ sandbox_provider()->ValidateFileSystemRootAndGetURL(
+ origin_url, type, create, callback.release());
+ MessageLoop::current()->RunAllPending();
+ break;
+ case 1:
+ sandbox_provider()->ValidateFileSystemRootAndGetPathOnFileThread(
+ origin_url, type, FilePath(), create);
+ break;
+ case 2:
+ sandbox_provider()->GetBaseDirectoryForOrigin(
+ origin_url, create);
+ break;
+ case 3:
+ sandbox_provider()->DeleteOriginDataOnFileThread(
+ NULL, origin_url, type);
+ break;
+ case 4:
+ sandbox_provider()->GetOriginsForTypeOnFileThread(
+ type, &origins);
+ break;
+ case 5:
+ sandbox_provider()->GetOriginsForHostOnFileThread(
+ type, host, &origins);
+ break;
+ case 6:
+ sandbox_provider()->GetOriginUsageOnFileThread(
+ origin_url, type);
+ break;
+ case 7:
+ // This case has to use an origin that already exists in the
+ // migrated data.
+ sandbox_provider()->UpdateOriginUsageOnFileThread(
+ NULL, kMigrationTestRecords[0].origin,
+ fileapi::kFileSystemTypeTemporary, delta);
+ break;
+ case 8:
+ // This case has to use a filesystem that already exists in the
+ // migrated data.
+ sandbox_provider()->StartUpdateOriginOnFileThread(
+ kMigrationTestRecords[0].origin, fileapi::kFileSystemTypeTemporary);
+ break;
+ case 9:
+ // This case has to use a filesystem that already exists in the
+ // migrated data.
+ sandbox_provider()->EndUpdateOriginOnFileThread(
+ kMigrationTestRecords[0].origin, fileapi::kFileSystemTypeTemporary);
+ break;
+ default:
+ FAIL();
+ break;
+ }
+ for (size_t i = 0; i < arraysize(kMigrationTestRecords); ++i) {
+ const MigrationTestCaseRecord& test_case = kMigrationTestRecords[i];
+ const GURL& origin_url = test_case.origin;
+ ASSERT_TRUE(test_case.has_temporary || test_case.has_persistent);
+ if (test_case.has_temporary)
+ ValidateDataInNewFileSystem(origin_url, kFileSystemTypeTemporary);
+ if (test_case.has_persistent)
+ ValidateDataInNewFileSystem(origin_url, kFileSystemTypePersistent);
+ }
+ }
+
+ protected:
+ ScopedTempDir data_dir_;
+ FileSystemPathManager* path_manager_;
+ scoped_refptr<FileSystemContext> file_system_context_;
+ base::ScopedCallbackFactory<SandboxMountPointProviderMigrationTest>
+ callback_factory_;
+};
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod0) {
+ RunMigrationTest(0);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod1) {
+ RunMigrationTest(1);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod2) {
+ RunMigrationTest(2);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod3) {
+ RunMigrationTest(3);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod4) {
+ RunMigrationTest(4);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod5) {
+ RunMigrationTest(5);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod6) {
+ RunMigrationTest(6);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod7) {
+ RunMigrationTest(7);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod8) {
+ RunMigrationTest(8);
+}
+
+TEST_F(SandboxMountPointProviderMigrationTest, TestMigrateViaMethod9) {
+ RunMigrationTest(9);
}
} // namespace fileapi