summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-10 00:02:31 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-10 00:02:31 +0000
commit7257f2bf72f4b9ccec1c94d3d67f9bb2f7dd5e97 (patch)
tree60559748d741157e6a674f1785ceed123208547d /webkit/fileapi
parent21dc604db6a9cf07d5277e755df77629352334af (diff)
downloadchromium_src-7257f2bf72f4b9ccec1c94d3d67f9bb2f7dd5e97.zip
chromium_src-7257f2bf72f4b9ccec1c94d3d67f9bb2f7dd5e97.tar.gz
chromium_src-7257f2bf72f4b9ccec1c94d3d67f9bb2f7dd5e97.tar.bz2
FileSystem code cleanup 2nd cut - introduce SandboxedFileSystemOperation
1. Introduced SandboxedFileSystemOperation. 2. Factored out most of the PathManager/QuotaManager related code from FileSystemDispatcherHost to the SandboxedFileSystemOperation. BUG=60243 TEST=none Review URL: http://codereview.chromium.org/4054003 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@65598 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r--webkit/fileapi/file_system_operation.h89
-rw-r--r--webkit/fileapi/sandboxed_file_system_context.cc34
-rw-r--r--webkit/fileapi/sandboxed_file_system_context.h48
-rw-r--r--webkit/fileapi/sandboxed_file_system_operation.cc184
-rw-r--r--webkit/fileapi/sandboxed_file_system_operation.h108
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi4
6 files changed, 424 insertions, 43 deletions
diff --git a/webkit/fileapi/file_system_operation.h b/webkit/fileapi/file_system_operation.h
index d76513f..01e2da1 100644
--- a/webkit/fileapi/file_system_operation.h
+++ b/webkit/fileapi/file_system_operation.h
@@ -37,49 +37,70 @@ class FileSystemOperation {
public:
FileSystemOperation(FileSystemCallbackDispatcher* dispatcher,
scoped_refptr<base::MessageLoopProxy> proxy);
- ~FileSystemOperation();
+ virtual ~FileSystemOperation();
- void CreateFile(const FilePath& path,
- bool exclusive);
+ virtual void CreateFile(const FilePath& path,
+ bool exclusive);
- void CreateDirectory(const FilePath& path,
- bool exclusive,
- bool recursive);
+ virtual void CreateDirectory(const FilePath& path,
+ bool exclusive,
+ bool recursive);
- void Copy(const FilePath& src_path,
- const FilePath& dest_path);
+ virtual void Copy(const FilePath& src_path,
+ const FilePath& dest_path);
- void Move(const FilePath& src_path,
- const FilePath& dest_path);
+ virtual void Move(const FilePath& src_path,
+ const FilePath& dest_path);
- void DirectoryExists(const FilePath& path);
+ virtual void DirectoryExists(const FilePath& path);
- void FileExists(const FilePath& path);
+ virtual void FileExists(const FilePath& path);
- void GetMetadata(const FilePath& path);
+ virtual void GetMetadata(const FilePath& path);
- void ReadDirectory(const FilePath& path);
+ virtual void ReadDirectory(const FilePath& path);
- void Remove(const FilePath& path, bool recursive);
+ virtual void Remove(const FilePath& path, bool recursive);
- void Write(
+ virtual void Write(
scoped_refptr<URLRequestContext> url_request_context,
const FilePath& path, const GURL& blob_url, int64 offset);
- void Truncate(const FilePath& path, int64 length);
+ virtual void Truncate(const FilePath& path, int64 length);
- void TouchFile(const FilePath& path,
+ virtual void TouchFile(const FilePath& path,
const base::Time& last_access_time,
const base::Time& last_modified_time);
// Try to cancel the current operation [we support cancelling write or
// truncate only]. Report failure for the current operation, then tell the
// passed-in operation to report success.
- void Cancel(FileSystemOperation* cancel_operation);
+ virtual void Cancel(FileSystemOperation* cancel_operation);
protected:
- // Proxy for calling file_util_proxy methods.
- scoped_refptr<base::MessageLoopProxy> proxy_;
+#ifndef NDEBUG
+ enum OperationType {
+ kOperationNone,
+ kOperationCreateFile,
+ kOperationCreateDirectory,
+ kOperationCopy,
+ kOperationMove,
+ kOperationDirectoryExists,
+ kOperationFileExists,
+ kOperationGetMetadata,
+ kOperationReadDirectory,
+ kOperationRemove,
+ kOperationWrite,
+ kOperationTruncate,
+ kOperationTouchFile,
+ kOperationCancel,
+ };
+
+ // A flag to make sure we call operation only once per instance.
+ OperationType pending_operation_;
+#endif
+
+ FileSystemCallbackDispatcher* dispatcher() const { return dispatcher_.get(); }
private:
// Callback for CreateFile for |exclusive|=true cases.
@@ -119,7 +140,11 @@ class FileSystemOperation {
base::PassPlatformFile file,
bool created);
+ // Proxy for calling file_util_proxy methods.
+ scoped_refptr<base::MessageLoopProxy> proxy_;
+
scoped_ptr<FileSystemCallbackDispatcher> dispatcher_;
+
base::ScopedCallbackFactory<FileSystemOperation> callback_factory_;
// These are all used only by Write().
@@ -128,28 +153,6 @@ class FileSystemOperation {
scoped_ptr<URLRequest> blob_request_;
FileSystemOperation* cancel_operation_;
-#ifndef NDEBUG
- enum OperationType {
- kOperationNone,
- kOperationCreateFile,
- kOperationCreateDirectory,
- kOperationCopy,
- kOperationMove,
- kOperationDirectoryExists,
- kOperationFileExists,
- kOperationGetMetadata,
- kOperationReadDirectory,
- kOperationRemove,
- kOperationWrite,
- kOperationTruncate,
- kOperationTouchFile,
- kOperationCancel,
- };
-
- // A flag to make sure we call operation only once per instance.
- OperationType pending_operation_;
-#endif
-
DISALLOW_COPY_AND_ASSIGN(FileSystemOperation);
};
diff --git a/webkit/fileapi/sandboxed_file_system_context.cc b/webkit/fileapi/sandboxed_file_system_context.cc
new file mode 100644
index 0000000..b71f57c
--- /dev/null
+++ b/webkit/fileapi/sandboxed_file_system_context.cc
@@ -0,0 +1,34 @@
+// Copyright (c) 2010 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 "webkit/fileapi/sandboxed_file_system_context.h"
+
+#include "base/file_path.h"
+#include "base/message_loop_proxy.h"
+#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/file_system_quota_manager.h"
+
+namespace fileapi {
+
+SandboxedFileSystemContext::SandboxedFileSystemContext(
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const FilePath& profile_path,
+ bool is_incognito,
+ bool allow_file_access,
+ bool unlimited_quota)
+ : path_manager_(new FileSystemPathManager(
+ file_message_loop, profile_path, is_incognito, allow_file_access)),
+ quota_manager_(new FileSystemQuotaManager(allow_file_access,
+ unlimited_quota)) {
+}
+
+SandboxedFileSystemContext::~SandboxedFileSystemContext() {
+}
+
+void SandboxedFileSystemContext::Shutdown() {
+ path_manager_.reset();
+ quota_manager_.reset();
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/sandboxed_file_system_context.h b/webkit/fileapi/sandboxed_file_system_context.h
new file mode 100644
index 0000000..ad6e2b8
--- /dev/null
+++ b/webkit/fileapi/sandboxed_file_system_context.h
@@ -0,0 +1,48 @@
+// Copyright (c) 2010 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_SANDBOXED_FILE_SYSTEM_CONTEXT_H_
+#define WEBKIT_FILEAPI_SANDBOXED_FILE_SYSTEM_CONTEXT_H_
+
+#include "base/ref_counted.h"
+#include "base/scoped_ptr.h"
+
+class FilePath;
+
+namespace base {
+class MessageLoopProxy;
+}
+
+namespace fileapi {
+
+class FileSystemPathManager;
+class FileSystemQuotaManager;
+
+// This class keeps and provides a sandboxed file system context.
+class SandboxedFileSystemContext {
+ public:
+ SandboxedFileSystemContext(
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ const FilePath& profile_path,
+ bool is_incognito,
+ bool allow_file_access_from_files,
+ bool unlimited_quota);
+ ~SandboxedFileSystemContext();
+
+ void Shutdown();
+
+ FileSystemPathManager* path_manager() { return path_manager_.get(); }
+ FileSystemQuotaManager* quota_manager() { return quota_manager_.get(); }
+
+ private:
+ bool allow_file_access_from_files_;
+ scoped_ptr<FileSystemPathManager> path_manager_;
+ scoped_ptr<FileSystemQuotaManager> quota_manager_;
+
+ DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxedFileSystemContext);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_SANDBOXED_FILE_SYSTEM_CONTEXT_H_
diff --git a/webkit/fileapi/sandboxed_file_system_operation.cc b/webkit/fileapi/sandboxed_file_system_operation.cc
new file mode 100644
index 0000000..fc77ce3
--- /dev/null
+++ b/webkit/fileapi/sandboxed_file_system_operation.cc
@@ -0,0 +1,184 @@
+// Copyright (c) 2010 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 "webkit/fileapi/sandboxed_file_system_operation.h"
+
+#include "net/url_request/url_request_context.h"
+#include "webkit/fileapi/file_system_callback_dispatcher.h"
+#include "webkit/fileapi/file_system_path_manager.h"
+#include "webkit/fileapi/file_system_quota_manager.h"
+#include "webkit/fileapi/sandboxed_file_system_context.h"
+
+namespace fileapi {
+
+SandboxedFileSystemOperation::SandboxedFileSystemOperation(
+ FileSystemCallbackDispatcher* dispatcher,
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ SandboxedFileSystemContext* file_system_context)
+ : FileSystemOperation(dispatcher, proxy),
+ file_system_context_(file_system_context),
+ callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
+ DCHECK(file_system_context_);
+}
+
+void SandboxedFileSystemOperation::OpenFileSystem(
+ const GURL& origin_url, fileapi::FileSystemType type, bool create) {
+#ifndef NDEBUG
+ DCHECK(kOperationNone == pending_operation_);
+ pending_operation_ = static_cast<FileSystemOperation::OperationType>(
+ kOperationOpenFileSystem);
+#endif
+
+ file_system_context_->path_manager()->GetFileSystemRootPath(
+ origin_url, type, create,
+ callback_factory_.NewCallback(
+ &SandboxedFileSystemOperation::DidGetRootPath));
+}
+
+void SandboxedFileSystemOperation::CreateFile(
+ const FilePath& path, bool exclusive) {
+ if (!VerifyFileSystemPathForWrite(path, true /* create */, 0))
+ return;
+ FileSystemOperation::CreateFile(path, exclusive);
+}
+
+void SandboxedFileSystemOperation::CreateDirectory(
+ const FilePath& path, bool exclusive, bool recursive) {
+ if (!VerifyFileSystemPathForWrite(path, true /* create */, 0))
+ return;
+ FileSystemOperation::CreateDirectory(path, exclusive, recursive);
+}
+
+void SandboxedFileSystemOperation::Copy(
+ const FilePath& src_path, const FilePath& dest_path) {
+ if (!VerifyFileSystemPathForRead(src_path) ||
+ !VerifyFileSystemPathForWrite(dest_path, true /* create */,
+ FileSystemQuotaManager::kUnknownSize))
+ return;
+ FileSystemOperation::Copy(src_path, dest_path);
+}
+
+void SandboxedFileSystemOperation::Move(
+ const FilePath& src_path, const FilePath& dest_path) {
+ if (!VerifyFileSystemPathForRead(src_path) ||
+ !VerifyFileSystemPathForWrite(dest_path, true /* create */,
+ FileSystemQuotaManager::kUnknownSize))
+ return;
+ FileSystemOperation::Move(src_path, dest_path);
+}
+
+void SandboxedFileSystemOperation::DirectoryExists(const FilePath& path) {
+ if (!VerifyFileSystemPathForRead(path))
+ return;
+ FileSystemOperation::DirectoryExists(path);
+}
+
+void SandboxedFileSystemOperation::FileExists(const FilePath& path) {
+ if (!VerifyFileSystemPathForRead(path))
+ return;
+ FileSystemOperation::FileExists(path);
+}
+
+void SandboxedFileSystemOperation::GetMetadata(const FilePath& path) {
+ if (!VerifyFileSystemPathForRead(path))
+ return;
+ FileSystemOperation::GetMetadata(path);
+}
+
+void SandboxedFileSystemOperation::ReadDirectory(const FilePath& path) {
+ if (!VerifyFileSystemPathForRead(path))
+ return;
+ FileSystemOperation::ReadDirectory(path);
+}
+
+void SandboxedFileSystemOperation::Remove(
+ const FilePath& path, bool recursive) {
+ if (!VerifyFileSystemPathForWrite(path, false /* create */, 0))
+ return;
+ FileSystemOperation::Remove(path, recursive);
+}
+
+void SandboxedFileSystemOperation::Write(
+ scoped_refptr<URLRequestContext> url_request_context,
+ const FilePath& path, const GURL& blob_url, int64 offset) {
+ if (!VerifyFileSystemPathForWrite(path, true /* create */,
+ FileSystemQuotaManager::kUnknownSize))
+ return;
+ FileSystemOperation::Write(url_request_context, path, blob_url, offset);
+}
+
+void SandboxedFileSystemOperation::Truncate(
+ const FilePath& path, int64 length) {
+ if (!VerifyFileSystemPathForWrite(path, false /* create */, 0))
+ return;
+ FileSystemOperation::Truncate(path, length);
+}
+
+void SandboxedFileSystemOperation::TouchFile(const FilePath& path,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time) {
+ if (!VerifyFileSystemPathForWrite(path, true /* create */, 0))
+ return;
+ FileSystemOperation::TouchFile(path, last_access_time, last_modified_time);
+}
+
+void SandboxedFileSystemOperation::DidGetRootPath(
+ bool success, const FilePath& path, const std::string& name) {
+ DCHECK(success || path.empty());
+ dispatcher()->DidOpenFileSystem(name, path);
+}
+
+bool SandboxedFileSystemOperation::VerifyFileSystemPathForRead(
+ const FilePath& path) {
+ // We may want do more checks, but for now it just checks if the given
+ // |path| is under the valid FileSystem root path for this host context.
+ if (!file_system_context_->path_manager()->CrackFileSystemPath(
+ path, NULL, NULL, NULL)) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return false;
+ }
+ return true;
+}
+
+bool SandboxedFileSystemOperation::VerifyFileSystemPathForWrite(
+ const FilePath& path, bool create, int64 growth) {
+ GURL origin_url;
+ FilePath virtual_path;
+ if (!file_system_context_->path_manager()->CrackFileSystemPath(
+ path, &origin_url, NULL, &virtual_path)) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return false;
+ }
+ // Any write access is disallowed on the root path.
+ if (virtual_path.value().length() == 0 ||
+ virtual_path.DirName().value() == virtual_path.value()) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return false;
+ }
+ if (create && file_system_context_->path_manager()->IsRestrictedFileName(
+ path.BaseName())) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return false;
+ }
+ // TODO(kinuko): For operations with kUnknownSize we'll eventually
+ // need to resolve what amount of size it's going to write.
+ if (!file_system_context_->quota_manager()->CheckOriginQuota(
+ origin_url, growth)) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_NO_SPACE);
+ return false;
+ }
+ return true;
+}
+
+bool SandboxedFileSystemOperation::CheckIfFilePathIsSafe(
+ const FilePath& path) {
+ if (file_system_context_->path_manager()->IsRestrictedFileName(
+ path.BaseName())) {
+ dispatcher()->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
+ return false;
+ }
+ return true;
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/sandboxed_file_system_operation.h b/webkit/fileapi/sandboxed_file_system_operation.h
new file mode 100644
index 0000000..088a5f3
--- /dev/null
+++ b/webkit/fileapi/sandboxed_file_system_operation.h
@@ -0,0 +1,108 @@
+// Copyright (c) 2010 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_SANDBOXED_FILE_SYSTEM_OPERATION_H_
+#define WEBKIT_FILEAPI_SANDBOXED_FILE_SYSTEM_OPERATION_H_
+
+#include "base/scoped_callback_factory.h"
+#include "webkit/fileapi/file_system_operation.h"
+#include "webkit/fileapi/file_system_types.h"
+
+namespace fileapi {
+
+class SandboxedFileSystemContext;
+
+// This class provides a 'sandboxed' access to the underlying file system,
+// that is:
+// 1. provides OpenFileSystem method that returns a (hidden) root path
+// that is given by |file_system_context|.
+// 2. enforces quota and file names/paths restrictions on each operation
+// via |file_system_context|.
+class SandboxedFileSystemOperation : public FileSystemOperation {
+ public:
+ // This class doesn't hold a reference or ownership of |file_system_context|.
+ // It is the caller's responsibility to keep the pointer alive *until*
+ // it calls any of the operation methods. The |file_system_context| won't be
+ // used in the callback path and can be deleted after the operation is
+ // made (e.g. after one of CreateFile, CreateDirectory, Copy, etc is called).
+ SandboxedFileSystemOperation(FileSystemCallbackDispatcher* dispatcher,
+ scoped_refptr<base::MessageLoopProxy> proxy,
+ SandboxedFileSystemContext* file_system_context);
+
+ void OpenFileSystem(const GURL& origin_url,
+ fileapi::FileSystemType type,
+ bool create);
+
+ // FileSystemOperation's methods.
+ virtual void CreateFile(const FilePath& path,
+ bool exclusive);
+ virtual void CreateDirectory(const FilePath& path,
+ bool exclusive,
+ bool recursive);
+ virtual void Copy(const FilePath& src_path,
+ const FilePath& dest_path);
+ virtual void Move(const FilePath& src_path,
+ const FilePath& dest_path);
+ virtual void DirectoryExists(const FilePath& path);
+ virtual void FileExists(const FilePath& path);
+ virtual void GetMetadata(const FilePath& path);
+ virtual void ReadDirectory(const FilePath& path);
+ virtual void Remove(const FilePath& path, bool recursive);
+ virtual void Write(
+ scoped_refptr<URLRequestContext> url_request_context,
+ const FilePath& path, const GURL& blob_url, int64 offset);
+ virtual void Truncate(const FilePath& path, int64 length);
+ virtual void TouchFile(const FilePath& path,
+ const base::Time& last_access_time,
+ const base::Time& last_modified_time);
+
+ private:
+ enum SandboxedFileSystemOperationType {
+ kOperationOpenFileSystem = 100,
+ };
+
+ // A callback used for OpenFileSystem.
+ void DidGetRootPath(bool success,
+ const FilePath& path,
+ const std::string& name);
+
+ // Checks the validity of a given |path| for reading.
+ // Returns true if the given |path| is a valid FileSystem path.
+ // Otherwise it calls dispatcher's DidFail method with
+ // PLATFORM_FILE_ERROR_SECURITY and returns false.
+ bool VerifyFileSystemPathForRead(const FilePath& path);
+
+ // Checks the validity of a given |path| for writing.
+ // Returns true if the given |path| is a valid FileSystem path, and
+ // its origin embedded in the path has the right to write as much as
+ // the given |growth|.
+ // Otherwise it fires dispatcher's DidFail method with
+ // PLATFORM_FILE_ERROR_SECURITY if the path is not valid for writing,
+ // or with PLATFORM_FILE_ERROR_NO_SPACE if the origin is not allowed to
+ // increase the usage by |growth|.
+ // In either case it returns false after firing DidFail.
+ // If |create| flag is true this also checks if the |path| contains
+ // any restricted names and chars. If it does, the call fires dispatcher's
+ // DidFail with PLATFORM_FILE_ERROR_SECURITY and returns false.
+ bool VerifyFileSystemPathForWrite(const FilePath& path,
+ bool create,
+ int64 growth);
+
+ // Checks if a given |path| does not contain any restricted names/chars
+ // for new files. Returns true if the given |path| is safe.
+ // Otherwise it fires dispatcher's DidFail method with
+ // PLATFORM_FILE_ERROR_SECURITY and returns false.
+ bool CheckIfFilePathIsSafe(const FilePath& path);
+
+ // Not owned. See the comment at the constructor.
+ SandboxedFileSystemContext* file_system_context_;
+
+ base::ScopedCallbackFactory<SandboxedFileSystemOperation> callback_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(SandboxedFileSystemOperation);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_SANDBOXED_FILE_SYSTEM_OPERATION_H_
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index de9e612..e380a2c 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -24,6 +24,10 @@
'file_system_types.h',
'file_writer_delegate.cc',
'file_writer_delegate.h',
+ 'sandboxed_file_system_context.cc',
+ 'sandboxed_file_system_context.h',
+ 'sandboxed_file_system_operation.cc',
+ 'sandboxed_file_system_operation.h',
'webfilewriter_base.cc',
'webfilewriter_base.h',
],