Add validation framework to Copy or Move operations in fileapi.
BUG=176566
Review URL: https://chromiumcodereview.appspot.com/12886042
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@192246 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
index 731b10ce..550bb61 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc
@@ -20,6 +20,7 @@
#include "webkit/chromeos/fileapi/remote_file_stream_writer.h"
#include "webkit/chromeos/fileapi/remote_file_system_operation.h"
#include "webkit/fileapi/async_file_util_adapter.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/external_mount_points.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
#include "webkit/fileapi/file_system_operation_context.h"
@@ -214,6 +215,20 @@
return local_file_util_.get();
}
+fileapi::CopyOrMoveFileValidatorFactory*
+CrosMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+ fileapi::FileSystemType type, base::PlatformFileError* error_code) {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ return NULL;
+}
+
+void CrosMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
+ fileapi::FileSystemType type,
+ scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
+ DCHECK(!factory);
+}
+
fileapi::FilePermissionPolicy CrosMountPointProvider::GetPermissionPolicy(
const fileapi::FileSystemURL& url, int permissions) const {
if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal &&
diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.h b/webkit/chromeos/fileapi/cros_mount_point_provider.h
index 21cb7cc..bf27785 100644
--- a/webkit/chromeos/fileapi/cros_mount_point_provider.h
+++ b/webkit/chromeos/fileapi/cros_mount_point_provider.h
@@ -19,6 +19,7 @@
namespace fileapi {
class AsyncFileUtilAdapter;
+class CopyOrMoveFileValidatorFactory;
class ExternalMountPoints;
class FileSystemFileUtil;
class FileSystemURL;
@@ -63,6 +64,13 @@
fileapi::FileSystemType type) OVERRIDE;
virtual fileapi::AsyncFileUtil* GetAsyncFileUtil(
fileapi::FileSystemType type) OVERRIDE;
+ virtual fileapi::CopyOrMoveFileValidatorFactory*
+ GetCopyOrMoveFileValidatorFactory(
+ fileapi::FileSystemType type,
+ base::PlatformFileError* error_code) OVERRIDE;
+ virtual void InitializeCopyOrMoveFileValidatorFactory(
+ fileapi::FileSystemType type,
+ scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) OVERRIDE;
virtual fileapi::FilePermissionPolicy GetPermissionPolicy(
const fileapi::FileSystemURL& url,
int permissions) const OVERRIDE;
diff --git a/webkit/fileapi/copy_or_move_file_validator.h b/webkit/fileapi/copy_or_move_file_validator.h
new file mode 100644
index 0000000..507a2766
--- /dev/null
+++ b/webkit/fileapi/copy_or_move_file_validator.h
@@ -0,0 +1,36 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_FILEAPI_COPY_OR_MOVE_FILE_VALIDATOR_H_
+#define WEBKIT_FILEAPI_COPY_OR_MOVE_FILE_VALIDATOR_H_
+
+#include "base/callback.h"
+#include "base/files/file_path.h"
+#include "base/platform_file.h"
+
+namespace fileapi {
+
+class CopyOrMoveFileValidator {
+ public:
+ // Callback that is invoked when validation completes. A result of
+ // base::PLATFORM_FILE_OK means the file validated.
+ typedef base::Callback<void(base::PlatformFileError result)> ResultCallback;
+
+ virtual ~CopyOrMoveFileValidator() {}
+
+ virtual void StartValidation(const ResultCallback& result_callback) = 0;
+};
+
+class CopyOrMoveFileValidatorFactory {
+ public:
+ virtual ~CopyOrMoveFileValidatorFactory() {}
+
+ // This method must always return a non-NULL validator.
+ virtual CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
+ const base::FilePath& platform_path) = 0;
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_COPY_OR_MOVE_FILE_VALIDATOR_H_
diff --git a/webkit/fileapi/copy_or_move_file_validator_unittest.cc b/webkit/fileapi/copy_or_move_file_validator_unittest.cc
new file mode 100644
index 0000000..7abc628
--- /dev/null
+++ b/webkit/fileapi/copy_or_move_file_validator_unittest.cc
@@ -0,0 +1,278 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/basictypes.h"
+#include "base/bind.h"
+#include "base/files/file_path.h"
+#include "base/files/scoped_temp_dir.h"
+#include "base/message_loop.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/fileapi/async_file_test_helper.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
+#include "webkit/fileapi/external_mount_points.h"
+#include "webkit/fileapi/file_system_context.h"
+#include "webkit/fileapi/file_system_mount_point_provider.h"
+#include "webkit/fileapi/file_system_task_runners.h"
+#include "webkit/fileapi/file_system_url.h"
+#include "webkit/fileapi/file_system_util.h"
+#include "webkit/fileapi/isolated_context.h"
+#include "webkit/fileapi/mock_file_system_options.h"
+#include "webkit/quota/mock_special_storage_policy.h"
+
+namespace fileapi {
+
+class CopyOrMoveFileValidatorTestHelper {
+ public:
+ CopyOrMoveFileValidatorTestHelper(
+ const GURL& origin,
+ FileSystemType src_type,
+ FileSystemType dest_type)
+ : origin_(origin),
+ src_type_(src_type),
+ dest_type_(dest_type) {}
+
+ ~CopyOrMoveFileValidatorTestHelper() {
+ file_system_context_ = NULL;
+ MessageLoop::current()->RunUntilIdle();
+ }
+
+ void SetUp() {
+ ASSERT_TRUE(base_.CreateUniqueTempDir());
+ base::FilePath base_dir = base_.path();
+ file_system_context_ = new FileSystemContext(
+ FileSystemTaskRunners::CreateMockTaskRunners(),
+ ExternalMountPoints::CreateRefCounted().get(),
+ make_scoped_refptr(new quota::MockSpecialStoragePolicy),
+ NULL,
+ base_dir,
+ CreateAllowFileAccessOptions());
+
+ // Prepare the origin's root directory.
+ if (src_type_ == kFileSystemTypeNativeMedia) {
+ base::FilePath src_path = base_dir.Append(FILE_PATH_LITERAL("src_media"));
+ file_util::CreateDirectory(src_path);
+ src_fsid_ = IsolatedContext::GetInstance()->RegisterFileSystemForPath(
+ kFileSystemTypeNativeMedia, src_path, NULL);
+ } else {
+ FileSystemMountPointProvider* mount_point_provider =
+ file_system_context_->GetMountPointProvider(src_type_);
+ mount_point_provider->GetFileSystemRootPathOnFileThread(
+ SourceURL(""),
+ true /* create */);
+ }
+ DCHECK_EQ(kFileSystemTypeNativeMedia, dest_type_);
+ base::FilePath dest_path = base_dir.Append(FILE_PATH_LITERAL("dest_media"));
+ file_util::CreateDirectory(dest_path);
+ dest_fsid_ = IsolatedContext::GetInstance()->RegisterFileSystemForPath(
+ kFileSystemTypeNativeMedia, dest_path, NULL);
+
+ copy_src_ = SourceURL("copy_src.jpg");
+ move_src_ = SourceURL("move_src.jpg");
+ copy_dest_ = DestURL("copy_dest.jpg");
+ move_dest_ = DestURL("move_dest.jpg");
+
+ ASSERT_EQ(base::PLATFORM_FILE_OK, CreateFile(copy_src_, 10));
+ ASSERT_EQ(base::PLATFORM_FILE_OK, CreateFile(move_src_, 10));
+
+ ASSERT_TRUE(FileExists(copy_src_, 10));
+ ASSERT_TRUE(FileExists(move_src_, 10));
+ ASSERT_FALSE(FileExists(copy_dest_, 10));
+ ASSERT_FALSE(FileExists(move_dest_, 10));
+ }
+
+ void SetMediaCopyOrMoveFileValidatorFactory(
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) {
+ FileSystemMountPointProvider* mount_point_provider =
+ file_system_context_->GetMountPointProvider(kFileSystemTypeNativeMedia);
+ mount_point_provider->InitializeCopyOrMoveFileValidatorFactory(
+ kFileSystemTypeNativeMedia, factory.Pass());
+ }
+
+ void CopyTest(base::PlatformFileError expected) {
+ ASSERT_TRUE(FileExists(copy_src_, 10));
+ ASSERT_FALSE(FileExists(copy_dest_, 10));
+
+ EXPECT_EQ(expected,
+ AsyncFileTestHelper::Copy(file_system_context_, copy_src_,
+ copy_dest_));
+
+ EXPECT_TRUE(FileExists(copy_src_, 10));
+ if (expected == base::PLATFORM_FILE_OK)
+ EXPECT_TRUE(FileExists(copy_dest_, 10));
+ else
+ EXPECT_FALSE(FileExists(copy_dest_, 10));
+ };
+
+ void MoveTest(base::PlatformFileError expected) {
+ ASSERT_TRUE(FileExists(move_src_, 10));
+ ASSERT_FALSE(FileExists(move_dest_, 10));
+
+ EXPECT_EQ(expected,
+ AsyncFileTestHelper::Move(file_system_context_, move_src_,
+ move_dest_));
+
+ if (expected == base::PLATFORM_FILE_OK) {
+ EXPECT_FALSE(FileExists(move_src_, 10));
+ EXPECT_TRUE(FileExists(move_dest_, 10));
+ } else {
+ EXPECT_TRUE(FileExists(move_src_, 10));
+ EXPECT_FALSE(FileExists(move_dest_, 10));
+ }
+ };
+
+ private:
+ FileSystemURL SourceURL(const std::string& path) {
+ if (src_type_ == kFileSystemTypeNativeMedia) {
+ std::string root_fs_url = GetIsolatedFileSystemRootURIString(
+ origin_, src_fsid_, "src_media/");
+ return file_system_context_->CrackURL(GURL(root_fs_url + path));
+ }
+ return file_system_context_->CreateCrackedFileSystemURL(
+ origin_, src_type_, base::FilePath::FromUTF8Unsafe(path));
+ }
+
+ FileSystemURL DestURL(const std::string& path) {
+ std::string root_fs_url = GetIsolatedFileSystemRootURIString(
+ origin_, dest_fsid_, "dest_media/");
+ return file_system_context_->CrackURL(GURL(root_fs_url + path));
+ }
+
+ base::PlatformFileError CreateFile(const FileSystemURL& url, size_t size) {
+ base::PlatformFileError result =
+ AsyncFileTestHelper::CreateFile(file_system_context_, url);
+ if (result != base::PLATFORM_FILE_OK)
+ return result;
+ return AsyncFileTestHelper::TruncateFile(file_system_context_, url, size);
+ }
+
+ bool FileExists(const FileSystemURL& url, int64 expected_size) {
+ return AsyncFileTestHelper::FileExists(
+ file_system_context_, url, expected_size);
+ }
+
+ base::ScopedTempDir base_;
+
+ const GURL origin_;
+
+ const FileSystemType src_type_;
+ const FileSystemType dest_type_;
+ std::string src_fsid_;
+ std::string dest_fsid_;
+
+ MessageLoop message_loop_;
+ scoped_refptr<FileSystemContext> file_system_context_;
+
+ FileSystemURL copy_src_;
+ FileSystemURL copy_dest_;
+ FileSystemURL move_src_;
+ FileSystemURL move_dest_;
+
+ DISALLOW_COPY_AND_ASSIGN(CopyOrMoveFileValidatorTestHelper);
+};
+
+class TestCopyOrMoveFileValidatorFactory
+ : public CopyOrMoveFileValidatorFactory {
+ public:
+ // A factory that creates validators that accept everything or nothing.
+ TestCopyOrMoveFileValidatorFactory(bool all_valid) : all_valid_(all_valid) {}
+ virtual ~TestCopyOrMoveFileValidatorFactory() {}
+
+ virtual CopyOrMoveFileValidator* CreateCopyOrMoveFileValidator(
+ const base::FilePath& /*platform_path*/) {
+ return new TestCopyOrMoveFileValidator(all_valid_);
+ }
+
+ private:
+ class TestCopyOrMoveFileValidator : public CopyOrMoveFileValidator {
+ public:
+ TestCopyOrMoveFileValidator(bool all_valid)
+ : result_(all_valid ? base::PLATFORM_FILE_OK
+ : base::PLATFORM_FILE_ERROR_SECURITY) {
+ }
+ virtual ~TestCopyOrMoveFileValidator() {}
+
+ virtual void StartValidation(const ResultCallback& result_callback) {
+ // Post the result since a real validator must do work asynchronously.
+ MessageLoop::current()->PostTask(FROM_HERE, base::Bind(result_callback,
+ result_));
+ }
+
+ private:
+ base::PlatformFileError result_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidator);
+ };
+
+ bool all_valid_;
+
+ DISALLOW_COPY_AND_ASSIGN(TestCopyOrMoveFileValidatorFactory);
+};
+
+TEST(CopyOrMoveFileValidatorTest, NoValidatorWithin6ameFSType) {
+ // Within a file system type, validation is not expected, so it should
+ // work for kFileSystemTypeNativeMedia without a validator set.
+ CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeNativeMedia,
+ kFileSystemTypeNativeMedia);
+ helper.SetUp();
+ helper.CopyTest(base::PLATFORM_FILE_OK);
+ helper.MoveTest(base::PLATFORM_FILE_OK);
+}
+
+TEST(CopyOrMoveFileValidatorTest, MissingValidator) {
+ // Copying or moving into a kFileSystemTypeNativeMedia requires a file
+ // validator. An error is expect if copy is attempted without a validator.
+ CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeTemporary,
+ kFileSystemTypeNativeMedia);
+ helper.SetUp();
+ helper.CopyTest(base::PLATFORM_FILE_ERROR_SECURITY);
+ helper.MoveTest(base::PLATFORM_FILE_ERROR_SECURITY);
+}
+
+TEST(CopyOrMoveFileValidatorTest, AcceptAll) {
+ CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeTemporary,
+ kFileSystemTypeNativeMedia);
+ helper.SetUp();
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
+ new TestCopyOrMoveFileValidatorFactory(true /*accept_all*/));
+ helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
+
+ helper.CopyTest(base::PLATFORM_FILE_OK);
+ helper.MoveTest(base::PLATFORM_FILE_OK);
+}
+
+TEST(CopyOrMoveFileValidatorTest, AcceptNone) {
+ CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeTemporary,
+ kFileSystemTypeNativeMedia);
+ helper.SetUp();
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory(
+ new TestCopyOrMoveFileValidatorFactory(false /*accept_all*/));
+ helper.SetMediaCopyOrMoveFileValidatorFactory(factory.Pass());
+
+ helper.CopyTest(base::PLATFORM_FILE_ERROR_SECURITY);
+ helper.MoveTest(base::PLATFORM_FILE_ERROR_SECURITY);
+}
+
+TEST(CopyOrMoveFileValidatorTest, OverrideValidator) {
+ // Once set, you can not override the validator.
+ CopyOrMoveFileValidatorTestHelper helper(GURL("http://foo"),
+ kFileSystemTypeTemporary,
+ kFileSystemTypeNativeMedia);
+ helper.SetUp();
+ scoped_ptr<CopyOrMoveFileValidatorFactory> reject_factory(
+ new TestCopyOrMoveFileValidatorFactory(false /*accept_all*/));
+ helper.SetMediaCopyOrMoveFileValidatorFactory(reject_factory.Pass());
+
+ scoped_ptr<CopyOrMoveFileValidatorFactory> accept_factory(
+ new TestCopyOrMoveFileValidatorFactory(true /*accept_all*/));
+ helper.SetMediaCopyOrMoveFileValidatorFactory(accept_factory.Pass());
+
+ helper.CopyTest(base::PLATFORM_FILE_ERROR_SECURITY);
+ helper.MoveTest(base::PLATFORM_FILE_ERROR_SECURITY);
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/cross_operation_delegate.cc b/webkit/fileapi/cross_operation_delegate.cc
index b7e391a..3ec57ec 100644
--- a/webkit/fileapi/cross_operation_delegate.cc
+++ b/webkit/fileapi/cross_operation_delegate.cc
@@ -6,6 +6,7 @@
#include "base/bind.h"
#include "webkit/blob/shareable_file_reference.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_operation_context.h"
#include "webkit/fileapi/file_system_util.h"
@@ -154,6 +155,35 @@
// TODO(kinuko): Otherwise create a FileStreamReader to perform a copy/move.
DCHECK(!platform_path.empty());
+ CopyOrMoveFileValidatorFactory* factory =
+ file_system_context()->GetCopyOrMoveFileValidatorFactory(
+ dest_root_.type(), &error);
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+ if (!factory) {
+ DidValidateFile(dest, callback, file_info, platform_path, error);
+ return;
+ }
+
+ validator_.reset(factory->CreateCopyOrMoveFileValidator(platform_path));
+ validator_->StartValidation(
+ base::Bind(&CrossOperationDelegate::DidValidateFile, AsWeakPtr(),
+ dest, callback, file_info, platform_path));
+}
+
+void CrossOperationDelegate::DidValidateFile(
+ const FileSystemURL& dest,
+ const StatusCallback& callback,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ base::PlatformFileError error) {
+ if (error != base::PLATFORM_FILE_OK) {
+ callback.Run(error);
+ return;
+ }
+
NewDestOperation()->CopyInForeignFile(platform_path, dest, callback);
}
diff --git a/webkit/fileapi/cross_operation_delegate.h b/webkit/fileapi/cross_operation_delegate.h
index 0aeabd3..77c15f5 100644
--- a/webkit/fileapi/cross_operation_delegate.h
+++ b/webkit/fileapi/cross_operation_delegate.h
@@ -17,6 +17,8 @@
namespace fileapi {
+class CopyOrMoveFileValidator;
+
// A delegate class for recursive copy or move operations.
class CrossOperationDelegate
: public RecursiveOperationDelegate,
@@ -61,6 +63,12 @@
const base::PlatformFileInfo& file_info,
const base::FilePath& platform_path,
const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref);
+ void DidValidateFile(
+ const FileSystemURL& dest,
+ const StatusCallback& callback,
+ const base::PlatformFileInfo& file_info,
+ const base::FilePath& platform_path,
+ base::PlatformFileError error);
void DidFinishCopy(
const FileSystemURL& src,
const StatusCallback& callback,
@@ -97,6 +105,8 @@
scoped_refptr<webkit_blob::ShareableFileReference> current_file_ref_;
+ scoped_ptr<CopyOrMoveFileValidator> validator_;
+
DISALLOW_COPY_AND_ASSIGN(CrossOperationDelegate);
};
diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc
index 33825f6..f487f54 100644
--- a/webkit/fileapi/file_system_context.cc
+++ b/webkit/fileapi/file_system_context.cc
@@ -8,6 +8,7 @@
#include "base/stl_util.h"
#include "base/single_thread_task_runner.h"
#include "googleurl/src/gurl.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/external_mount_points.h"
#include "webkit/fileapi/file_system_file_util.h"
#include "webkit/fileapi/file_system_operation.h"
@@ -133,6 +134,19 @@
return mount_point_provider->GetAsyncFileUtil(type);
}
+CopyOrMoveFileValidatorFactory*
+FileSystemContext::GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type, base::PlatformFileError* error_code) const {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ FileSystemMountPointProvider* mount_point_provider =
+ GetMountPointProvider(type);
+ if (!mount_point_provider)
+ return NULL;
+ return mount_point_provider->GetCopyOrMoveFileValidatorFactory(
+ type, error_code);
+}
+
FileSystemMountPointProvider* FileSystemContext::GetMountPointProvider(
FileSystemType type) const {
switch (type) {
diff --git a/webkit/fileapi/file_system_context.h b/webkit/fileapi/file_system_context.h
index 1a938e2..f0daf11 100644
--- a/webkit/fileapi/file_system_context.h
+++ b/webkit/fileapi/file_system_context.h
@@ -41,6 +41,7 @@
namespace fileapi {
class AsyncFileUtil;
+class CopyOrMoveFileValidatorFactory;
class ExternalFileSystemMountPointProvider;
class ExternalMountPoints;
class FileSystemFileUtil;
@@ -97,6 +98,12 @@
// Returns the appropriate AsyncFileUtil instance for the given |type|.
AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) const;
+ // Returns the appropriate CopyOrMoveFileValidatorFactory for the given
+ // |type|. If |error_code| is PLATFORM_FILE_OK and the result is NULL,
+ // then no validator is required.
+ CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type, base::PlatformFileError* error_code) const;
+
// Returns the mount point provider instance for the given |type|.
// This may return NULL if it is given an invalid or unsupported filesystem
// type.
diff --git a/webkit/fileapi/file_system_mount_point_provider.h b/webkit/fileapi/file_system_mount_point_provider.h
index 976d4605..066c2ab 100644
--- a/webkit/fileapi/file_system_mount_point_provider.h
+++ b/webkit/fileapi/file_system_mount_point_provider.h
@@ -10,6 +10,7 @@
#include "base/callback_forward.h"
#include "base/files/file_path.h"
+#include "base/memory/scoped_ptr.h"
#include "base/platform_file.h"
#include "webkit/fileapi/file_permission_policy.h"
#include "webkit/fileapi/file_system_types.h"
@@ -22,6 +23,7 @@
namespace fileapi {
class AsyncFileUtil;
+class CopyOrMoveFileValidatorFactory;
class FileSystemURL;
class FileStreamWriter;
class FileSystemContext;
@@ -68,6 +70,18 @@
// Returns the specialized AsyncFileUtil for this mount point.
virtual AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) = 0;
+ // Returns the specialized CopyOrMoveFileValidatorFactory for this mount
+ // point and |type|. If |error_code| is PLATFORM_FILE_OK and the result
+ // is NULL, then no validator is required.
+ virtual CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type, base::PlatformFileError* error_code) = 0;
+
+ // Initialize the CopyOrMoveFileValidatorFactory. Invalid to call more than
+ // once.
+ virtual void InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) = 0;
+
// Returns file permission policy we should apply for the given |url|.
virtual FilePermissionPolicy GetPermissionPolicy(
const FileSystemURL& url,
diff --git a/webkit/fileapi/isolated_mount_point_provider.cc b/webkit/fileapi/isolated_mount_point_provider.cc
index c3e3d3c..78ed482 100644
--- a/webkit/fileapi/isolated_mount_point_provider.cc
+++ b/webkit/fileapi/isolated_mount_point_provider.cc
@@ -14,6 +14,7 @@
#include "base/sequenced_task_runner.h"
#include "webkit/blob/local_file_stream_reader.h"
#include "webkit/fileapi/async_file_util_adapter.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/file_system_callback_dispatcher.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
@@ -122,6 +123,46 @@
return NULL;
}
+CopyOrMoveFileValidatorFactory*
+IsolatedMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type, base::PlatformFileError* error_code) {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ switch (type) {
+ case kFileSystemTypeNativeLocal:
+ case kFileSystemTypeDragged:
+ return NULL;
+ case kFileSystemTypeNativeMedia:
+ case kFileSystemTypeDeviceMedia:
+ if (!media_copy_or_move_file_validator_factory_) {
+ *error_code = base::PLATFORM_FILE_ERROR_SECURITY;
+ return NULL;
+ }
+ return media_copy_or_move_file_validator_factory_.get();
+ default:
+ NOTREACHED();
+ }
+ return NULL;
+}
+
+void IsolatedMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) {
+ switch (type) {
+ case kFileSystemTypeNativeLocal:
+ case kFileSystemTypeDragged:
+ DCHECK(factory == NULL);
+ break;
+ case kFileSystemTypeNativeMedia:
+ case kFileSystemTypeDeviceMedia:
+ if (!media_copy_or_move_file_validator_factory_)
+ media_copy_or_move_file_validator_factory_.reset(factory.release());
+ break;
+ default:
+ NOTREACHED();
+ }
+}
+
FilePermissionPolicy IsolatedMountPointProvider::GetPermissionPolicy(
const FileSystemURL& url, int permissions) const {
if (url.type() == kFileSystemTypeDragged && url.path().empty()) {
diff --git a/webkit/fileapi/isolated_mount_point_provider.h b/webkit/fileapi/isolated_mount_point_provider.h
index f0713aa..09e5d52 100644
--- a/webkit/fileapi/isolated_mount_point_provider.h
+++ b/webkit/fileapi/isolated_mount_point_provider.h
@@ -35,6 +35,12 @@
bool create) OVERRIDE;
virtual FileSystemFileUtil* GetFileUtil(FileSystemType type) OVERRIDE;
virtual AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) OVERRIDE;
+ virtual CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) OVERRIDE;
+ virtual void InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) OVERRIDE;
virtual FilePermissionPolicy GetPermissionPolicy(
const FileSystemURL& url,
int permissions) const OVERRIDE;
@@ -63,6 +69,8 @@
const base::FilePath profile_path_;
scoped_ptr<MediaPathFilter> media_path_filter_;
+ scoped_ptr<CopyOrMoveFileValidatorFactory>
+ media_copy_or_move_file_validator_factory_;
scoped_ptr<AsyncFileUtilAdapter> isolated_file_util_;
scoped_ptr<AsyncFileUtilAdapter> dragged_file_util_;
diff --git a/webkit/fileapi/sandbox_mount_point_provider.cc b/webkit/fileapi/sandbox_mount_point_provider.cc
index 3cb3bd55..da1ea76 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.cc
+++ b/webkit/fileapi/sandbox_mount_point_provider.cc
@@ -13,6 +13,7 @@
#include "googleurl/src/gurl.h"
#include "net/base/net_util.h"
#include "webkit/fileapi/async_file_util_adapter.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/file_system_context.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
#include "webkit/fileapi/file_system_operation_context.h"
@@ -262,6 +263,21 @@
return sandbox_file_util_.get();
}
+CopyOrMoveFileValidatorFactory*
+SandboxMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ return NULL;
+}
+
+void SandboxMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) {
+ DCHECK(!factory);
+}
+
FilePermissionPolicy SandboxMountPointProvider::GetPermissionPolicy(
const FileSystemURL& url, int permissions) const {
if (!CanHandleType(url.type()) || !IsAllowedScheme(url.origin()))
diff --git a/webkit/fileapi/sandbox_mount_point_provider.h b/webkit/fileapi/sandbox_mount_point_provider.h
index 1752b8a..e8fe024 100644
--- a/webkit/fileapi/sandbox_mount_point_provider.h
+++ b/webkit/fileapi/sandbox_mount_point_provider.h
@@ -89,6 +89,12 @@
bool create) OVERRIDE;
virtual FileSystemFileUtil* GetFileUtil(FileSystemType type) OVERRIDE;
virtual AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) OVERRIDE;
+ virtual CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) OVERRIDE;
+ virtual void InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) OVERRIDE;
virtual FilePermissionPolicy GetPermissionPolicy(
const FileSystemURL& url,
int permissions) const OVERRIDE;
diff --git a/webkit/fileapi/test_mount_point_provider.cc b/webkit/fileapi/test_mount_point_provider.cc
index 58cc910..5599c983 100644
--- a/webkit/fileapi/test_mount_point_provider.cc
+++ b/webkit/fileapi/test_mount_point_provider.cc
@@ -10,6 +10,7 @@
#include "base/file_util.h"
#include "base/sequenced_task_runner.h"
+#include "webkit/fileapi/copy_or_move_file_validator.h"
#include "webkit/fileapi/file_observers.h"
#include "webkit/fileapi/file_system_file_stream_reader.h"
#include "webkit/fileapi/file_system_operation_context.h"
@@ -111,6 +112,19 @@
return local_file_util_.get();
}
+CopyOrMoveFileValidatorFactory*
+TestMountPointProvider::GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type, base::PlatformFileError* error_code) {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ return NULL;
+}
+
+void TestMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type, scoped_ptr<CopyOrMoveFileValidatorFactory> factory) {
+ DCHECK(!factory);
+}
+
FilePermissionPolicy TestMountPointProvider::GetPermissionPolicy(
const FileSystemURL& url, int permissions) const {
return FILE_PERMISSION_ALWAYS_DENY;
diff --git a/webkit/fileapi/test_mount_point_provider.h b/webkit/fileapi/test_mount_point_provider.h
index c6d510be..8ad2308 100644
--- a/webkit/fileapi/test_mount_point_provider.h
+++ b/webkit/fileapi/test_mount_point_provider.h
@@ -44,6 +44,12 @@
bool create) OVERRIDE;
virtual FileSystemFileUtil* GetFileUtil(FileSystemType type) OVERRIDE;
virtual AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) OVERRIDE;
+ virtual CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) OVERRIDE;
+ virtual void InitializeCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ scoped_ptr<CopyOrMoveFileValidatorFactory> factory) OVERRIDE;
virtual FilePermissionPolicy GetPermissionPolicy(
const FileSystemURL& url,
int permissions) const OVERRIDE;
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index 5ce925e5..b6b9ba0 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -8,6 +8,7 @@
'../fileapi/async_file_util.h',
'../fileapi/async_file_util_adapter.cc',
'../fileapi/async_file_util_adapter.h',
+ '../fileapi/copy_or_move_file_validator.h',
'../fileapi/cross_operation_delegate.cc',
'../fileapi/cross_operation_delegate.h',
'../fileapi/external_mount_points.cc',