summaryrefslogtreecommitdiffstats
path: root/webkit/fileapi/file_system_operation.cc
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 05:15:53 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-02-14 05:15:53 +0000
commit397281fdb6003ab5b86ead542a46e3d82aa2be1f (patch)
tree6d7a2d27edfb8b3790dd4a199d2e32283206fcce /webkit/fileapi/file_system_operation.cc
parentc10878accf5f6c12c471d77d20b32ef3e84f5693 (diff)
downloadchromium_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.cc160
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