diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-14 05:15:53 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-02-14 05:15:53 +0000 |
commit | 397281fdb6003ab5b86ead542a46e3d82aa2be1f (patch) | |
tree | 6d7a2d27edfb8b3790dd4a199d2e32283206fcce /webkit/fileapi | |
parent | c10878accf5f6c12c471d77d20b32ef3e84f5693 (diff) | |
download | chromium_src-397281fdb6003ab5b86ead542a46e3d82aa2be1f.zip chromium_src-397281fdb6003ab5b86ead542a46e3d82aa2be1f.tar.gz chromium_src-397281fdb6003ab5b86ead542a46e3d82aa2be1f.tar.bz2 |
Cleanup SandboxedFileSystem* and merge them into FileSystem* for simplicity.
Based on our rough discussion over emails, I just went ahead and did the cleanup.
BUG=none
TEST=none
Review URL: http://codereview.chromium.org/6471018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@74786 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/fileapi')
-rw-r--r-- | webkit/fileapi/file_system_context.cc (renamed from webkit/fileapi/sandboxed_file_system_context.cc) | 14 | ||||
-rw-r--r-- | webkit/fileapi/file_system_context.h (renamed from webkit/fileapi/sandboxed_file_system_context.h) | 22 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation.cc | 160 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation.h | 151 | ||||
-rw-r--r-- | webkit/fileapi/file_system_operation_unittest.cc | 9 | ||||
-rw-r--r-- | webkit/fileapi/sandboxed_file_system_operation.cc | 202 | ||||
-rw-r--r-- | webkit/fileapi/sandboxed_file_system_operation.h | 102 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 6 |
8 files changed, 259 insertions, 407 deletions
diff --git a/webkit/fileapi/sandboxed_file_system_context.cc b/webkit/fileapi/file_system_context.cc index 1fd458d..c0546d8 100644 --- a/webkit/fileapi/sandboxed_file_system_context.cc +++ b/webkit/fileapi/file_system_context.cc @@ -2,7 +2,7 @@ // 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 "webkit/fileapi/file_system_context.h" #include "base/file_util.h" #include "base/message_loop_proxy.h" @@ -12,7 +12,7 @@ namespace fileapi { -SandboxedFileSystemContext::SandboxedFileSystemContext( +FileSystemContext::FileSystemContext( scoped_refptr<base::MessageLoopProxy> file_message_loop, scoped_refptr<base::MessageLoopProxy> io_message_loop, const FilePath& profile_path, @@ -29,10 +29,10 @@ SandboxedFileSystemContext::SandboxedFileSystemContext( file_message_loop, profile_path, is_incognito)) { } -SandboxedFileSystemContext::~SandboxedFileSystemContext() { +FileSystemContext::~FileSystemContext() { } -void SandboxedFileSystemContext::DeleteDataForOriginOnFileThread( +void FileSystemContext::DeleteDataForOriginOnFileThread( const GURL& origin_url) { DCHECK(path_manager_.get()); DCHECK(file_message_loop_->BelongsToCurrentThread()); @@ -45,17 +45,17 @@ void SandboxedFileSystemContext::DeleteDataForOriginOnFileThread( file_util::Delete(path_for_origin, true /* recursive */); } -void SandboxedFileSystemContext::SetOriginQuotaUnlimited(const GURL& url) { +void FileSystemContext::SetOriginQuotaUnlimited(const GURL& url) { DCHECK(io_message_loop_->BelongsToCurrentThread()); quota_manager()->SetOriginQuotaUnlimited(url); } -void SandboxedFileSystemContext::ResetOriginQuotaUnlimited(const GURL& url) { +void FileSystemContext::ResetOriginQuotaUnlimited(const GURL& url) { DCHECK(io_message_loop_->BelongsToCurrentThread()); quota_manager()->ResetOriginQuotaUnlimited(url); } -void SandboxedFileSystemContext::DeleteOnCorrectThread() const { +void FileSystemContext::DeleteOnCorrectThread() const { if (!io_message_loop_->BelongsToCurrentThread()) { io_message_loop_->DeleteSoon(FROM_HERE, this); return; diff --git a/webkit/fileapi/sandboxed_file_system_context.h b/webkit/fileapi/file_system_context.h index e3b7a67..5c94c5f 100644 --- a/webkit/fileapi/sandboxed_file_system_context.h +++ b/webkit/fileapi/file_system_context.h @@ -2,8 +2,8 @@ // 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_ +#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_CONTEXT_H_ +#define WEBKIT_FILEAPI_FILE_SYSTEM_CONTEXT_H_ #include "base/ref_counted.h" #include "base/scoped_ptr.h" @@ -20,23 +20,23 @@ namespace fileapi { class FileSystemPathManager; class FileSystemQuotaManager; class FileSystemUsageTracker; -class SandboxedFileSystemContext; +class FileSystemContext; struct DefaultContextDeleter; -// This class keeps and provides a sandboxed file system context. -class SandboxedFileSystemContext - : public base::RefCountedThreadSafe<SandboxedFileSystemContext, +// This class keeps and provides a file system context for FileSystem API. +class FileSystemContext + : public base::RefCountedThreadSafe<FileSystemContext, DefaultContextDeleter> { public: - SandboxedFileSystemContext( + FileSystemContext( scoped_refptr<base::MessageLoopProxy> file_message_loop, scoped_refptr<base::MessageLoopProxy> io_message_loop, const FilePath& profile_path, bool is_incognito, bool allow_file_access_from_files, bool unlimited_quota); - ~SandboxedFileSystemContext(); + ~FileSystemContext(); void DeleteDataForOriginOnFileThread(const GURL& origin_url); @@ -58,15 +58,15 @@ class SandboxedFileSystemContext scoped_ptr<FileSystemQuotaManager> quota_manager_; scoped_ptr<FileSystemUsageTracker> usage_tracker_; - DISALLOW_IMPLICIT_CONSTRUCTORS(SandboxedFileSystemContext); + DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext); }; struct DefaultContextDeleter { - static void Destruct(const SandboxedFileSystemContext* context) { + static void Destruct(const FileSystemContext* context) { context->DeleteOnCorrectThread(); } }; } // namespace fileapi -#endif // WEBKIT_FILEAPI_SANDBOXED_FILE_SYSTEM_CONTEXT_H_ +#endif // WEBKIT_FILEAPI_FILE_SYSTEM_CONTEXT_H_ diff --git a/webkit/fileapi/file_system_operation.cc b/webkit/fileapi/file_system_operation.cc index bd0d7e5..cea953e 100644 --- a/webkit/fileapi/file_system_operation.cc +++ b/webkit/fileapi/file_system_operation.cc @@ -7,15 +7,20 @@ #include "base/time.h" #include "net/url_request/url_request_context.h" #include "webkit/fileapi/file_system_callback_dispatcher.h" +#include "webkit/fileapi/file_system_context.h" +#include "webkit/fileapi/file_system_path_manager.h" +#include "webkit/fileapi/file_system_quota_manager.h" #include "webkit/fileapi/file_writer_delegate.h" namespace fileapi { FileSystemOperation::FileSystemOperation( FileSystemCallbackDispatcher* dispatcher, - scoped_refptr<base::MessageLoopProxy> proxy) + scoped_refptr<base::MessageLoopProxy> proxy, + FileSystemContext* file_system_context) : proxy_(proxy), dispatcher_(dispatcher), + file_system_context_(file_system_context), callback_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { DCHECK(dispatcher); #ifndef NDEBUG @@ -28,6 +33,20 @@ FileSystemOperation::~FileSystemOperation() { base::FileUtilProxy::Close(proxy_, file_writer_delegate_->file(), NULL); } +void FileSystemOperation::OpenFileSystem( + const GURL& origin_url, fileapi::FileSystemType type, bool create) { +#ifndef NDEBUG + DCHECK(kOperationNone == pending_operation_); + pending_operation_ = static_cast<FileSystemOperation::OperationType>( + kOperationOpenFileSystem); +#endif + + DCHECK(file_system_context_.get()); + file_system_context_->path_manager()->GetFileSystemRootPath( + origin_url, type, create, + callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath)); +} + void FileSystemOperation::CreateFile(const FilePath& path, bool exclusive) { #ifndef NDEBUG @@ -35,6 +54,10 @@ void FileSystemOperation::CreateFile(const FilePath& path, pending_operation_ = kOperationCreateFile; #endif + if (!VerifyFileSystemPathForWrite(path, true /* create */, 0)) { + delete this; + return; + } base::FileUtilProxy::EnsureFileExists( proxy_, path, callback_factory_.NewCallback( exclusive ? &FileSystemOperation::DidEnsureFileExistsExclusive @@ -49,6 +72,10 @@ void FileSystemOperation::CreateDirectory(const FilePath& path, pending_operation_ = kOperationCreateDirectory; #endif + if (!VerifyFileSystemPathForWrite(path, true /* create */, 0)) { + delete this; + return; + } base::FileUtilProxy::CreateDirectory( proxy_, path, exclusive, recursive, callback_factory_.NewCallback( &FileSystemOperation::DidFinishFileOperation)); @@ -61,6 +88,12 @@ void FileSystemOperation::Copy(const FilePath& src_path, pending_operation_ = kOperationCopy; #endif + if (!VerifyFileSystemPathForRead(src_path) || + !VerifyFileSystemPathForWrite(dest_path, true /* create */, + FileSystemQuotaManager::kUnknownSize)) { + delete this; + return; + } base::FileUtilProxy::Copy(proxy_, src_path, dest_path, callback_factory_.NewCallback( &FileSystemOperation::DidFinishFileOperation)); @@ -73,6 +106,12 @@ void FileSystemOperation::Move(const FilePath& src_path, pending_operation_ = kOperationMove; #endif + if (!VerifyFileSystemPathForRead(src_path) || + !VerifyFileSystemPathForWrite(dest_path, true /* create */, + FileSystemQuotaManager::kUnknownSize)) { + delete this; + return; + } base::FileUtilProxy::Move(proxy_, src_path, dest_path, callback_factory_.NewCallback( &FileSystemOperation::DidFinishFileOperation)); @@ -84,6 +123,10 @@ void FileSystemOperation::DirectoryExists(const FilePath& path) { pending_operation_ = kOperationDirectoryExists; #endif + if (!VerifyFileSystemPathForRead(path)) { + delete this; + return; + } base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( &FileSystemOperation::DidDirectoryExists)); } @@ -94,6 +137,10 @@ void FileSystemOperation::FileExists(const FilePath& path) { pending_operation_ = kOperationFileExists; #endif + if (!VerifyFileSystemPathForRead(path)) { + delete this; + return; + } base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( &FileSystemOperation::DidFileExists)); } @@ -104,6 +151,10 @@ void FileSystemOperation::GetMetadata(const FilePath& path) { pending_operation_ = kOperationGetMetadata; #endif + if (!VerifyFileSystemPathForRead(path)) { + delete this; + return; + } base::FileUtilProxy::GetFileInfo(proxy_, path, callback_factory_.NewCallback( &FileSystemOperation::DidGetMetadata)); } @@ -114,6 +165,10 @@ void FileSystemOperation::ReadDirectory(const FilePath& path) { pending_operation_ = kOperationReadDirectory; #endif + if (!VerifyFileSystemPathForRead(path)) { + delete this; + return; + } base::FileUtilProxy::ReadDirectory(proxy_, path, callback_factory_.NewCallback( &FileSystemOperation::DidReadDirectory)); @@ -125,6 +180,10 @@ void FileSystemOperation::Remove(const FilePath& path, bool recursive) { pending_operation_ = kOperationRemove; #endif + if (!VerifyFileSystemPathForWrite(path, false /* create */, 0)) { + delete this; + return; + } base::FileUtilProxy::Delete(proxy_, path, recursive, callback_factory_.NewCallback( &FileSystemOperation::DidFinishFileOperation)); @@ -139,6 +198,11 @@ void FileSystemOperation::Write( DCHECK(kOperationNone == pending_operation_); pending_operation_ = kOperationWrite; #endif + if (!VerifyFileSystemPathForWrite(path, true /* create */, + FileSystemQuotaManager::kUnknownSize)) { + delete this; + return; + } DCHECK(blob_url.is_valid()); file_writer_delegate_.reset(new FileWriterDelegate(this, offset)); blob_request_.reset( @@ -153,23 +217,15 @@ void FileSystemOperation::Write( &FileSystemOperation::OnFileOpenedForWrite)); } -void FileSystemOperation::OnFileOpenedForWrite( - base::PlatformFileError rv, - base::PassPlatformFile file, - bool created) { - if (base::PLATFORM_FILE_OK != rv) { - dispatcher_->DidFail(rv); - delete this; - return; - } - file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); -} - void FileSystemOperation::Truncate(const FilePath& path, int64 length) { #ifndef NDEBUG DCHECK(kOperationNone == pending_operation_); pending_operation_ = kOperationTruncate; #endif + if (!VerifyFileSystemPathForWrite(path, false /* create */, 0)) { + delete this; + return; + } base::FileUtilProxy::Truncate(proxy_, path, length, callback_factory_.NewCallback( &FileSystemOperation::DidFinishFileOperation)); @@ -183,6 +239,10 @@ void FileSystemOperation::TouchFile(const FilePath& path, pending_operation_ = kOperationTouchFile; #endif + if (!VerifyFileSystemPathForWrite(path, true /* create */, 0)) { + delete this; + return; + } base::FileUtilProxy::Touch( proxy_, path, last_access_time, last_modified_time, callback_factory_.NewCallback(&FileSystemOperation::DidTouchFile)); @@ -206,7 +266,7 @@ void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) { blob_request_->Cancel(); dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); - cancel_operation->dispatcher()->DidSucceed(); + cancel_operation->dispatcher_->DidSucceed(); delete this; } else { #ifndef NDEBUG @@ -221,6 +281,13 @@ void FileSystemOperation::Cancel(FileSystemOperation* cancel_operation_ptr) { } } +void FileSystemOperation::DidGetRootPath( + bool success, const FilePath& path, const std::string& name) { + DCHECK(success || path.empty()); + dispatcher_->DidOpenFileSystem(name, path); + delete this; +} + void FileSystemOperation::DidEnsureFileExistsExclusive( base::PlatformFileError rv, bool created) { if (rv == base::PLATFORM_FILE_OK && !created) { @@ -243,7 +310,7 @@ void FileSystemOperation::DidFinishFileOperation( #endif dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_ABORT); - cancel_operation_->dispatcher()->DidSucceed(); + cancel_operation_->dispatcher_->DidSucceed(); } else if (rv == base::PLATFORM_FILE_OK) { dispatcher_->DidSucceed(); } else { @@ -320,4 +387,67 @@ void FileSystemOperation::DidTouchFile(base::PlatformFileError rv) { delete this; } +void FileSystemOperation::OnFileOpenedForWrite( + base::PlatformFileError rv, + base::PassPlatformFile file, + bool created) { + if (base::PLATFORM_FILE_OK != rv) { + dispatcher_->DidFail(rv); + delete this; + return; + } + file_writer_delegate_->Start(file.ReleaseValue(), blob_request_.get()); +} + +bool FileSystemOperation::VerifyFileSystemPathForRead( + const FilePath& path) { + // If we have no context, we just allow any operations. + if (!file_system_context_.get()) + return true; + + // 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 FileSystemOperation::VerifyFileSystemPathForWrite( + const FilePath& path, bool create, int64 growth) { + GURL origin_url; + FilePath virtual_path; + + // If we have no context, we just allow any operations. + if (!file_system_context_.get()) + return true; + + 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; +} + } // namespace fileapi diff --git a/webkit/fileapi/file_system_operation.h b/webkit/fileapi/file_system_operation.h index 1b52e22..6542806 100644 --- a/webkit/fileapi/file_system_operation.h +++ b/webkit/fileapi/file_system_operation.h @@ -15,6 +15,7 @@ #include "base/scoped_callback_factory.h" #include "base/scoped_ptr.h" #include "googleurl/src/gurl.h" +#include "webkit/fileapi/file_system_types.h" namespace base { class Time; @@ -30,6 +31,7 @@ class GURL; namespace fileapi { class FileSystemCallbackDispatcher; +class FileSystemContext; class FileWriterDelegate; // This class is designed to serve one-time file system operation per instance. @@ -42,74 +44,47 @@ class FileSystemOperation { public: // |dispatcher| will be owned by this class. FileSystemOperation(FileSystemCallbackDispatcher* dispatcher, - scoped_refptr<base::MessageLoopProxy> proxy); + scoped_refptr<base::MessageLoopProxy> proxy, + FileSystemContext* file_system_context); virtual ~FileSystemOperation(); - 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<net::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); + void OpenFileSystem(const GURL& origin_url, + fileapi::FileSystemType type, + bool create); + void CreateFile(const FilePath& path, + bool exclusive); + void CreateDirectory(const FilePath& path, + bool exclusive, + bool recursive); + void Copy(const FilePath& src_path, + const FilePath& dest_path); + void Move(const FilePath& src_path, + const FilePath& dest_path); + void DirectoryExists(const FilePath& path); + void FileExists(const FilePath& path); + void GetMetadata(const FilePath& path); + void ReadDirectory(const FilePath& path); + void Remove(const FilePath& path, bool recursive); + void Write(scoped_refptr<net::URLRequestContext> url_request_context, + const FilePath& path, + const GURL& blob_url, + int64 offset); + void Truncate(const FilePath& path, int64 length); + 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. - virtual void Cancel(FileSystemOperation* cancel_operation); - - protected: -#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(); } + void Cancel(FileSystemOperation* cancel_operation); private: + // A callback used for OpenFileSystem. + void DidGetRootPath(bool success, + const FilePath& path, + const std::string& name); + // Callback for CreateFile for |exclusive|=true cases. void DidEnsureFileExistsExclusive(base::PlatformFileError rv, bool created); @@ -123,22 +98,17 @@ class FileSystemOperation { void DidDirectoryExists(base::PlatformFileError rv, const base::PlatformFileInfo& file_info); - void DidFileExists(base::PlatformFileError rv, const base::PlatformFileInfo& file_info); - void DidGetMetadata(base::PlatformFileError rv, const base::PlatformFileInfo& file_info); - void DidReadDirectory( base::PlatformFileError rv, const std::vector<base::FileUtilProxy::Entry>& entries); - void DidWrite( base::PlatformFileError rv, int64 bytes, bool complete); - void DidTouchFile(base::PlatformFileError rv); // Helper for Write(). @@ -147,11 +117,62 @@ class FileSystemOperation { base::PassPlatformFile file, bool created); + // 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. + // (Note: this doesn't delete this when it calls DidFail and returns false; + // it's the caller's responsibility.) + 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. + // (Note: this doesn't delete this when it calls DidFail and returns false; + // it's the caller's responsibility.) + bool VerifyFileSystemPathForWrite(const FilePath& path, + bool create, + int64 growth); + +#ifndef NDEBUG + enum OperationType { + kOperationNone, + kOperationOpenFileSystem, + 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 + // Proxy for calling file_util_proxy methods. scoped_refptr<base::MessageLoopProxy> proxy_; scoped_ptr<FileSystemCallbackDispatcher> dispatcher_; + scoped_refptr<FileSystemContext> file_system_context_; + base::ScopedCallbackFactory<FileSystemOperation> callback_factory_; // These are all used only by Write(). diff --git a/webkit/fileapi/file_system_operation_unittest.cc b/webkit/fileapi/file_system_operation_unittest.cc index 7917d31..b535676 100644 --- a/webkit/fileapi/file_system_operation_unittest.cc +++ b/webkit/fileapi/file_system_operation_unittest.cc @@ -23,6 +23,12 @@ static bool FileExists(FilePath path) { class MockDispatcher; +// Test class for FileSystemOperation. Note that this just tests low-level +// operations but doesn't test OpenFileSystem or any additional checks +// that require FileSystemContext (e.g. sandboxed paths, unlimited_storage +// quota handling etc). +// See SimpleFileSystem for more complete test environment for sandboxed +// FileSystem. class FileSystemOperationTest : public testing::Test { public: FileSystemOperationTest() @@ -93,7 +99,8 @@ class MockDispatcher : public FileSystemCallbackDispatcher { FileSystemOperation* FileSystemOperationTest::operation() { return new FileSystemOperation( new MockDispatcher(this), - base::MessageLoopProxy::CreateForCurrentThread()); + base::MessageLoopProxy::CreateForCurrentThread(), + NULL); } TEST_F(FileSystemOperationTest, TestMoveFailureSrcDoesntExist) { diff --git a/webkit/fileapi/sandboxed_file_system_operation.cc b/webkit/fileapi/sandboxed_file_system_operation.cc deleted file mode 100644 index 08569f9..0000000 --- a/webkit/fileapi/sandboxed_file_system_operation.cc +++ /dev/null @@ -1,202 +0,0 @@ -// Copyright (c) 2011 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, - scoped_refptr<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_); -} - -SandboxedFileSystemOperation::~SandboxedFileSystemOperation() {} - -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)) { - delete this; - return; - } - FileSystemOperation::CreateFile(path, exclusive); -} - -void SandboxedFileSystemOperation::CreateDirectory( - const FilePath& path, bool exclusive, bool recursive) { - if (!VerifyFileSystemPathForWrite(path, true /* create */, 0)) { - delete this; - 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)) { - delete this; - 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)) { - delete this; - return; - } - FileSystemOperation::Move(src_path, dest_path); -} - -void SandboxedFileSystemOperation::DirectoryExists(const FilePath& path) { - if (!VerifyFileSystemPathForRead(path)) { - delete this; - return; - } - FileSystemOperation::DirectoryExists(path); -} - -void SandboxedFileSystemOperation::FileExists(const FilePath& path) { - if (!VerifyFileSystemPathForRead(path)) { - delete this; - return; - } - FileSystemOperation::FileExists(path); -} - -void SandboxedFileSystemOperation::GetMetadata(const FilePath& path) { - if (!VerifyFileSystemPathForRead(path)) { - delete this; - return; - } - FileSystemOperation::GetMetadata(path); -} - -void SandboxedFileSystemOperation::ReadDirectory(const FilePath& path) { - if (!VerifyFileSystemPathForRead(path)) { - delete this; - return; - } - FileSystemOperation::ReadDirectory(path); -} - -void SandboxedFileSystemOperation::Remove( - const FilePath& path, bool recursive) { - if (!VerifyFileSystemPathForWrite(path, false /* create */, 0)) { - delete this; - return; - } - FileSystemOperation::Remove(path, recursive); -} - -void SandboxedFileSystemOperation::Write( - scoped_refptr<net::URLRequestContext> url_request_context, - const FilePath& path, const GURL& blob_url, int64 offset) { - if (!VerifyFileSystemPathForWrite(path, true /* create */, - FileSystemQuotaManager::kUnknownSize)) { - delete this; - return; - } - FileSystemOperation::Write(url_request_context, path, blob_url, offset); -} - -void SandboxedFileSystemOperation::Truncate( - const FilePath& path, int64 length) { - if (!VerifyFileSystemPathForWrite(path, false /* create */, 0)) { - delete this; - 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)) { - delete this; - 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); - delete this; -} - -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; -} - -} // namespace fileapi diff --git a/webkit/fileapi/sandboxed_file_system_operation.h b/webkit/fileapi/sandboxed_file_system_operation.h deleted file mode 100644 index bea905d..0000000 --- a/webkit/fileapi/sandboxed_file_system_operation.h +++ /dev/null @@ -1,102 +0,0 @@ -// Copyright (c) 2011 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: - SandboxedFileSystemOperation( - FileSystemCallbackDispatcher* dispatcher, - scoped_refptr<base::MessageLoopProxy> proxy, - scoped_refptr<SandboxedFileSystemContext> file_system_context); - virtual ~SandboxedFileSystemOperation(); - - 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<net::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. - // (Note: this doesn't delete this when it calls DidFail and returns false; - // it's the caller's responsibility.) - 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. - // (Note: this doesn't delete this when it calls DidFail and returns false; - // it's the caller's responsibility.) - bool VerifyFileSystemPathForWrite(const FilePath& path, - bool create, - int64 growth); - - scoped_refptr<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 c1beb11..c082f2c 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -15,6 +15,8 @@ ], 'sources': [ 'file_system_callback_dispatcher.h', + 'file_system_context.cc', + 'file_system_context.h', 'file_system_dir_url_request_job.cc', 'file_system_dir_url_request_job.h', 'file_system_operation.cc', @@ -32,10 +34,6 @@ 'file_system_util.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', ], |