| Index: webkit/fileapi/sandboxed_file_system_operation.cc
|
| diff --git a/webkit/fileapi/sandboxed_file_system_operation.cc b/webkit/fileapi/sandboxed_file_system_operation.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..fc77ce319a6a00182cb14adbce171a72ff396fa7
|
| --- /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
|
|
|