| Index: webkit/fileapi/file_system_operation.cc
|
| ===================================================================
|
| --- webkit/fileapi/file_system_operation.cc (revision 81454)
|
| +++ webkit/fileapi/file_system_operation.cc (working copy)
|
| @@ -5,6 +5,8 @@
|
| #include "webkit/fileapi/file_system_operation.h"
|
|
|
| #include "base/time.h"
|
| +#include "base/utf_string_conversions.h"
|
| +#include "net/base/escape.h"
|
| #include "net/url_request/url_request_context.h"
|
| #include "webkit/fileapi/file_system_callback_dispatcher.h"
|
| #include "webkit/fileapi/file_system_context.h"
|
| @@ -63,7 +65,7 @@
|
| callback_factory_.NewCallback(&FileSystemOperation::DidGetRootPath));
|
| }
|
|
|
| -void FileSystemOperation::CreateFile(const FilePath& path,
|
| +void FileSystemOperation::CreateFile(const GURL& path,
|
| bool exclusive) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| @@ -86,7 +88,7 @@
|
| : &FileSystemOperation::DidEnsureFileExistsNonExclusive));
|
| }
|
|
|
| -void FileSystemOperation::CreateDirectory(const FilePath& path,
|
| +void FileSystemOperation::CreateDirectory(const GURL& path,
|
| bool exclusive,
|
| bool recursive) {
|
| #ifndef NDEBUG
|
| @@ -110,8 +112,8 @@
|
| &FileSystemOperation::DidFinishFileOperation));
|
| }
|
|
|
| -void FileSystemOperation::Copy(const FilePath& src_path,
|
| - const FilePath& dest_path) {
|
| +void FileSystemOperation::Copy(const GURL& src_path,
|
| + const GURL& dest_path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationCopy;
|
| @@ -149,8 +151,8 @@
|
| &FileSystemOperation::DidFinishFileOperation));
|
| }
|
|
|
| -void FileSystemOperation::Move(const FilePath& src_path,
|
| - const FilePath& dest_path) {
|
| +void FileSystemOperation::Move(const GURL& src_path,
|
| + const GURL& dest_path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationMove;
|
| @@ -162,6 +164,8 @@
|
| FileSystemType src_type;
|
| FileSystemType dest_type;
|
|
|
| + //TODO(ericu): Move alters the source path as well, so we should be checking
|
| + //both for write!
|
| if (!VerifyFileSystemPathForRead(src_path, &src_origin_url, &src_type,
|
| &virtual_path_0) ||
|
| !VerifyFileSystemPathForWrite(dest_path, true /* create */,
|
| @@ -186,7 +190,7 @@
|
| &FileSystemOperation::DidFinishFileOperation));
|
| }
|
|
|
| -void FileSystemOperation::DirectoryExists(const FilePath& path) {
|
| +void FileSystemOperation::DirectoryExists(const GURL& path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationDirectoryExists;
|
| @@ -207,7 +211,7 @@
|
| &FileSystemOperation::DidDirectoryExists));
|
| }
|
|
|
| -void FileSystemOperation::FileExists(const FilePath& path) {
|
| +void FileSystemOperation::FileExists(const GURL& path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationFileExists;
|
| @@ -228,7 +232,7 @@
|
| &FileSystemOperation::DidFileExists));
|
| }
|
|
|
| -void FileSystemOperation::GetMetadata(const FilePath& path) {
|
| +void FileSystemOperation::GetMetadata(const GURL& path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationGetMetadata;
|
| @@ -249,7 +253,7 @@
|
| &FileSystemOperation::DidGetMetadata));
|
| }
|
|
|
| -void FileSystemOperation::ReadDirectory(const FilePath& path) {
|
| +void FileSystemOperation::ReadDirectory(const GURL& path) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationReadDirectory;
|
| @@ -270,7 +274,7 @@
|
| &FileSystemOperation::DidReadDirectory));
|
| }
|
|
|
| -void FileSystemOperation::Remove(const FilePath& path, bool recursive) {
|
| +void FileSystemOperation::Remove(const GURL& path, bool recursive) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationRemove;
|
| @@ -294,7 +298,7 @@
|
|
|
| void FileSystemOperation::Write(
|
| scoped_refptr<net::URLRequestContext> url_request_context,
|
| - const FilePath& path,
|
| + const GURL& path,
|
| const GURL& blob_url,
|
| int64 offset) {
|
| #ifndef NDEBUG
|
| @@ -326,7 +330,7 @@
|
| &FileSystemOperation::OnFileOpenedForWrite));
|
| }
|
|
|
| -void FileSystemOperation::Truncate(const FilePath& path, int64 length) {
|
| +void FileSystemOperation::Truncate(const GURL& path, int64 length) {
|
| #ifndef NDEBUG
|
| DCHECK(kOperationNone == pending_operation_);
|
| pending_operation_ = kOperationTruncate;
|
| @@ -347,7 +351,7 @@
|
| &FileSystemOperation::DidFinishFileOperation));
|
| }
|
|
|
| -void FileSystemOperation::TouchFile(const FilePath& path,
|
| +void FileSystemOperation::TouchFile(const GURL& path,
|
| const base::Time& last_access_time,
|
| const base::Time& last_modified_time) {
|
| #ifndef NDEBUG
|
| @@ -408,14 +412,13 @@
|
| bool success,
|
| const FilePath& path, const std::string& name) {
|
| DCHECK(success || path.empty());
|
| - FilePath result;
|
| + GURL result;
|
| // We ignore the path, and return a URL instead. The point was just to verify
|
| // that we could create/find the path.
|
| if (success) {
|
| - GURL root_url = GetFileSystemRootURI(
|
| + result = GetFileSystemRootURI(
|
| file_system_operation_context_.src_origin_url(),
|
| file_system_operation_context_.src_type());
|
| - result = FilePath().AppendASCII(root_url.spec());
|
| }
|
| dispatcher_->DidOpenFileSystem(name, result);
|
| delete this;
|
| @@ -537,45 +540,77 @@
|
| }
|
|
|
| bool FileSystemOperation::VerifyFileSystemPathForRead(
|
| - const FilePath& path, GURL* origin_url, FileSystemType* type,
|
| + const GURL& path, GURL* origin_url, FileSystemType* type,
|
| FilePath* virtual_path) {
|
|
|
| // If we have no context, we just allow any operations, for testing.
|
| // TODO(ericu): Revisit this hack for security.
|
| if (!file_system_context()) {
|
| - *virtual_path = path;
|
| +#ifdef OS_WIN
|
| + // On Windows, the path will look like /C:/foo/bar; we need to remove the
|
| + // leading slash to make it valid. But if it's empty, we shouldn't do
|
| + // anything.
|
| + std::string temp = UnescapeURLComponent(path.path(),
|
| + UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
|
| + if (temp.size())
|
| + temp = temp.substr(1);
|
| + *virtual_path = FilePath(UTF8ToWide(temp)).NormalizeWindowsPathSeparators();
|
| +#else
|
| + *virtual_path = FilePath(path.path());
|
| +#endif
|
| *type = file_system_operation_context_.src_type();
|
| + *origin_url = file_system_operation_context_.src_origin_url();
|
| 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, origin_url, type, virtual_path)) {
|
| + // URL is valid.
|
| + if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) {
|
| dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
|
| return false;
|
| }
|
| + if (!file_system_context()->path_manager()->IsAllowedFileSystemType(
|
| + *origin_url, *type)) {
|
| + dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
|
| + return false;
|
| + }
|
|
|
| return true;
|
| }
|
|
|
| bool FileSystemOperation::VerifyFileSystemPathForWrite(
|
| - const FilePath& path, bool create, GURL* origin_url, FileSystemType* type,
|
| + const GURL& path, bool create, GURL* origin_url, FileSystemType* type,
|
| FilePath* virtual_path) {
|
|
|
| // If we have no context, we just allow any operations, for testing.
|
| // TODO(ericu): Revisit this hack for security.
|
| if (!file_system_context()) {
|
| - *virtual_path = path;
|
| +#ifdef OS_WIN
|
| + // On Windows, the path will look like /C:/foo/bar; we need to remove the
|
| + // leading slash to make it valid. But if it's empty, we shouldn't do
|
| + // anything.
|
| + std::string temp = UnescapeURLComponent(path.path(),
|
| + UnescapeRule::SPACES | UnescapeRule::URL_SPECIAL_CHARS);
|
| + if (temp.size())
|
| + temp = temp.substr(1);
|
| + *virtual_path = FilePath(UTF8ToWide(temp)).NormalizeWindowsPathSeparators();
|
| +#else
|
| + *virtual_path = FilePath(path.path());
|
| +#endif
|
| *type = file_system_operation_context_.dest_type();
|
| + *origin_url = file_system_operation_context_.dest_origin_url();
|
| return true;
|
| }
|
|
|
| - if (!file_system_context()->path_manager()->CrackFileSystemPath(
|
| - path, origin_url, type, virtual_path)) {
|
| + if (!CrackFileSystemURL(path, origin_url, type, virtual_path)) {
|
| dispatcher_->DidFail(base::PLATFORM_FILE_ERROR_SECURITY);
|
| return false;
|
| }
|
| + if (!file_system_context()->path_manager()->IsAllowedFileSystemType(
|
| + *origin_url, *type)) {
|
| + 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()) {
|
|
|