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/file_system_operation.cc | |
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/file_system_operation.cc')
-rw-r--r-- | webkit/fileapi/file_system_operation.cc | 160 |
1 files changed, 145 insertions, 15 deletions
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 |