diff options
author | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 06:15:43 +0000 |
---|---|---|
committer | kinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-12 06:15:43 +0000 |
commit | eafe2e7b3164af96be59ff2e76bc90e9c113790b (patch) | |
tree | d98279db131c2455dcd7d7ac6323a2fcca471402 | |
parent | 9e0315287c149e48fb31d15a121699898c917b0b (diff) | |
download | chromium_src-eafe2e7b3164af96be59ff2e76bc90e9c113790b.zip chromium_src-eafe2e7b3164af96be59ff2e76bc90e9c113790b.tar.gz chromium_src-eafe2e7b3164af96be59ff2e76bc90e9c113790b.tar.bz2 |
Refactor out path-related methods from file_system_host_context into a separated module.
No functionality changes; code relocation/cleanup only.
This change is necessary to improve test coverage for another coming change
(hide the FileSystem's root directory under 'unpredictrable' location).
BUG=none
TEST=FileSystemPathManager.*
Review URL: http://codereview.chromium.org/3703003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62259 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/file_system/file_system_dispatcher_host.cc | 10 | ||||
-rw-r--r-- | chrome/browser/file_system/file_system_host_context.cc | 193 | ||||
-rw-r--r-- | chrome/browser/file_system/file_system_host_context.h | 40 | ||||
-rw-r--r-- | chrome/browser/renderer_host/browser_render_process_host.cc | 4 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | tools/valgrind/memcheck/suppressions.txt | 12 | ||||
-rw-r--r-- | webkit/fileapi/file_system_path_manager.cc | 215 | ||||
-rw-r--r-- | webkit/fileapi/file_system_path_manager.h | 69 | ||||
-rw-r--r-- | webkit/fileapi/file_system_path_manager_unittest.cc (renamed from chrome/browser/file_system/file_system_host_context_unittest.cc) | 57 | ||||
-rw-r--r-- | webkit/fileapi/webkit_fileapi.gypi | 2 | ||||
-rw-r--r-- | webkit/tools/test_shell/test_shell.gypi | 1 |
11 files changed, 330 insertions, 274 deletions
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.cc b/chrome/browser/file_system/file_system_dispatcher_host.cc index df77a57..84990ac 100644 --- a/chrome/browser/file_system/file_system_dispatcher_host.cc +++ b/chrome/browser/file_system/file_system_dispatcher_host.cc @@ -20,6 +20,7 @@ #include "chrome/common/render_messages_params.h" #include "googleurl/src/gurl.h" #include "net/url_request/url_request_context.h" +#include "webkit/fileapi/file_system_path_manager.h" #include "webkit/fileapi/file_system_quota.h" using fileapi::FileSystemQuota; @@ -158,7 +159,8 @@ void FileSystemDispatcherHost::OnOpenFileSystem( FilePath root_path; std::string name; - if (!context_->GetFileSystemRootPath(origin_url, type, &root_path, &name)) { + if (!context_->path_manager()->GetFileSystemRootPath( + origin_url, type, &root_path, &name)) { Send(new ViewMsg_OpenFileSystemRequest_Complete( request_id, false, std::string(), FilePath())); return; @@ -297,7 +299,7 @@ bool FileSystemDispatcherHost::CheckValidFileSystemPath( const FilePath& path, int request_id) { // 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 (!context_->CheckValidFileSystemPath(path)) { + if (!context_->path_manager()->CheckValidFileSystemPath(path)) { Send(new ViewMsg_FileSystem_DidFail( request_id, base::PLATFORM_FILE_ERROR_SECURITY)); return false; @@ -308,7 +310,7 @@ bool FileSystemDispatcherHost::CheckValidFileSystemPath( bool FileSystemDispatcherHost::CheckQuotaForPath( const FilePath& path, int64 growth, int request_id) { GURL origin_url; - if (!context_->GetOriginFromPath(path, &origin_url)) { + if (!context_->path_manager()->GetOriginFromPath(path, &origin_url)) { // Appears to be an ill-formed path or for an unallowed scheme. Send(new ViewMsg_FileSystem_DidFail( request_id, base::PLATFORM_FILE_ERROR_SECURITY)); @@ -326,7 +328,7 @@ bool FileSystemDispatcherHost::CheckQuotaForPath( bool FileSystemDispatcherHost::CheckIfFilePathIsSafe( const FilePath& path, int request_id) { - if (context_->IsRestrictedFileName(path.BaseName())) { + if (context_->path_manager()->IsRestrictedFileName(path.BaseName())) { Send(new ViewMsg_FileSystem_DidFail( request_id, base::PLATFORM_FILE_ERROR_SECURITY)); return false; diff --git a/chrome/browser/file_system/file_system_host_context.cc b/chrome/browser/file_system/file_system_host_context.cc index 37c2b8c..f529864 100644 --- a/chrome/browser/file_system/file_system_host_context.cc +++ b/chrome/browser/file_system/file_system_host_context.cc @@ -11,186 +11,15 @@ #include "base/utf_string_conversions.h" #include "chrome/common/chrome_switches.h" #include "googleurl/src/gurl.h" -#include "third_party/WebKit/WebKit/chromium/public/WebCString.h" -#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h" -#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" #include "webkit/glue/webkit_glue.h" -// We use some of WebKit types for conversions between storage identifiers -// and origin URLs. -using WebKit::WebFileSystem; -using WebKit::WebSecurityOrigin; -using WebKit::WebString; - -const FilePath::CharType FileSystemHostContext::kFileSystemDirectory[] = - FILE_PATH_LITERAL("FileSystem"); - -const char FileSystemHostContext::kPersistentName[] = "Persistent"; -const char FileSystemHostContext::kTemporaryName[] = "Temporary"; - -namespace { - -// Restricted names. -// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions -static const char* const kRestrictedNames[] = { - "con", "prn", "aux", "nul", - "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", - "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", -}; - -// Restricted chars. -static const FilePath::CharType kRestrictedChars[] = { - '/', '\\', '<', '>', ':', '?', '*', '"', '|', -}; - -static inline std::string FilePathStringToASCII( - const FilePath::StringType& path_string) { -#if defined(OS_WIN) - return WideToASCII(path_string); -#elif defined(OS_POSIX) - return path_string; -#endif -} - -} // anonymous namespace - FileSystemHostContext::FileSystemHostContext( const FilePath& data_path, bool is_incognito) - : base_path_(data_path.Append(kFileSystemDirectory)), - is_incognito_(is_incognito), - quota_manager_(new fileapi::FileSystemQuota()) { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - allow_file_access_from_files_ = command_line.HasSwitch( - switches::kAllowFileAccessFromFiles); -} - -bool FileSystemHostContext::GetFileSystemRootPath( - const GURL& origin_url, fileapi::FileSystemType type, - FilePath* root_path, std::string* name) const { - // TODO(kinuko): should return an isolated temporary file system space. - if (is_incognito_) - return false; - - if (!IsAllowedScheme(origin_url)) - return false; - - std::string storage_identifier = GetStorageIdentifierFromURL(origin_url); - switch (type) { - case fileapi::kFileSystemTypeTemporary: - if (root_path) - *root_path = base_path_.AppendASCII(storage_identifier) - .AppendASCII(kTemporaryName); - if (name) - *name = storage_identifier + ":" + kTemporaryName; - return true; - case fileapi::kFileSystemTypePersistent: - if (root_path) - *root_path = base_path_.AppendASCII(storage_identifier) - .AppendASCII(kPersistentName); - if (name) - *name = storage_identifier + ":" + kPersistentName; - return true; - } - LOG(WARNING) << "Unknown filesystem type is requested:" << type; - return false; -} - -bool FileSystemHostContext::CheckValidFileSystemPath( - const FilePath& path) const { - // Any paths that includes parent references are considered invalid. - if (path.ReferencesParent()) - return false; - - // The path should be a child of the profile FileSystem path. - FilePath relative; - if (!base_path_.AppendRelativePath(path, &relative)) - return false; - - // The relative path from the profile FileSystem path should at least - // contains two components, one for storage identifier and the other for type. - std::vector<FilePath::StringType> components; - relative.GetComponents(&components); - if (components.size() < 2) - return false; - - // The second component of the relative path to the root directory - // must be kPersistent or kTemporary. - if (!IsStringASCII(components[1])) - return false; - - std::string ascii_type_component = FilePathStringToASCII(components[1]); - if (ascii_type_component != kPersistentName && - ascii_type_component != kTemporaryName) - return false; - - return true; -} - -bool FileSystemHostContext::GetOriginFromPath( - const FilePath& path, GURL* origin_url) { - DCHECK(origin_url); - FilePath relative; - if (!base_path_.AppendRelativePath(path, &relative)) { - // The path should be a child of the profile's FileSystem path. - return false; - } - std::vector<FilePath::StringType> components; - relative.GetComponents(&components); - if (components.size() < 2) { - // The relative path should at least contain storage identifier and type. - return false; - } - WebSecurityOrigin web_security_origin = - WebSecurityOrigin::createFromDatabaseIdentifier( - webkit_glue::FilePathStringToWebString(components[0])); - *origin_url = GURL(web_security_origin.toString()); - - // We need this work-around for file:/// URIs as - // createFromDatabaseIdentifier returns empty origin_url for them. - if (allow_file_access_from_files_ && origin_url->spec().empty() && - components[0].find(FILE_PATH_LITERAL("file")) == 0) { - *origin_url = GURL("file:///"); - return true; - } - - return IsAllowedScheme(*origin_url); -} - -bool FileSystemHostContext::IsAllowedScheme(const GURL& url) const { - // Basically we only accept http or https. We allow file:// URLs - // only if --allow-file-access-from-files flag is given. - return url.SchemeIs("http") || url.SchemeIs("https") || - (url.SchemeIsFile() && allow_file_access_from_files_); -} - -bool FileSystemHostContext::IsRestrictedFileName( - const FilePath& filename) const { - if (filename.value().size() == 0) - return false; - - if (IsWhitespace(filename.value()[filename.value().size() - 1]) || - filename.value()[filename.value().size() - 1] == '.') - return true; - - std::string filename_lower = StringToLowerASCII( - FilePathStringToASCII(filename.value())); - - for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { - // Exact match. - if (filename_lower == kRestrictedNames[i]) - return true; - // Starts with "RESTRICTED_NAME.". - if (filename_lower.find(std::string(kRestrictedNames[i]) + ".") == 0) - return true; - } - - for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { - if (filename.value().find(kRestrictedChars[i]) != - FilePath::StringType::npos) - return true; - } - - return false; + : allow_file_access_from_files_(CommandLine::ForCurrentProcess()->HasSwitch( + switches::kAllowFileAccessFromFiles)), + quota_manager_(new fileapi::FileSystemQuota()), + path_manager_(new fileapi::FileSystemPathManager( + data_path, is_incognito, allow_file_access_from_files_)) { } bool FileSystemHostContext::CheckOriginQuota(const GURL& url, int64 growth) { @@ -211,15 +40,3 @@ void FileSystemHostContext::ResetOriginQuotaUnlimited(const GURL& url) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); quota_manager_->ResetOriginQuotaUnlimited(url); } - -std::string FileSystemHostContext::GetStorageIdentifierFromURL( - const GURL& url) { - WebKit::WebSecurityOrigin web_security_origin = - WebKit::WebSecurityOrigin::createFromString(UTF8ToUTF16(url.spec())); - return web_security_origin.databaseIdentifier().utf8(); -} - -COMPILE_ASSERT(int(WebFileSystem::TypeTemporary) == \ - int(fileapi::kFileSystemTypeTemporary), mismatching_enums); -COMPILE_ASSERT(int(WebFileSystem::TypePersistent) == \ - int(fileapi::kFileSystemTypePersistent), mismatching_enums); diff --git a/chrome/browser/file_system/file_system_host_context.h b/chrome/browser/file_system/file_system_host_context.h index be5b5bd..6c12c67 100644 --- a/chrome/browser/file_system/file_system_host_context.h +++ b/chrome/browser/file_system/file_system_host_context.h @@ -9,8 +9,9 @@ #include "base/ref_counted.h" #include "base/scoped_ptr.h" #include "chrome/browser/chrome_thread.h" -#include "webkit/fileapi/file_system_quota.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/file_system_path_manager.h" +#include "webkit/fileapi/file_system_quota.h" class GURL; @@ -21,52 +22,19 @@ class FileSystemHostContext BrowserThread::DeleteOnIOThread> { public: FileSystemHostContext(const FilePath& data_path, bool is_incognito); - const FilePath& base_path() const { return base_path_; } - bool is_incognito() const { return is_incognito_; } - - // Returns the root path and name for the file system specified by given - // |origin_url| and |type|. Returns true if the file system is available - // for the profile and |root_path| and |name| are filled successfully. - bool GetFileSystemRootPath(const GURL& origin_url, - fileapi::FileSystemType type, - FilePath* root_path, - std::string* name) const; - - // Checks if a given |path| is in the FileSystem base directory. - bool CheckValidFileSystemPath(const FilePath& path) const; - - // Retrieves the origin URL for the given |path| and populates - // |origin_url|. It returns false when the given |path| is not a - // valid filesystem path. - bool GetOriginFromPath(const FilePath& path, GURL* origin_url); - - // Returns true if the given |url|'s scheme is allowed to access - // filesystem. - bool IsAllowedScheme(const GURL& url) const; - - // Checks if a given |filename| contains any restricted names/chars in it. - bool IsRestrictedFileName(const FilePath& filename) const; // Quota related methods. bool CheckOriginQuota(const GURL& url, int64 growth); void SetOriginQuotaUnlimited(const GURL& url); void ResetOriginQuotaUnlimited(const GURL& url); - // The FileSystem directory name. - static const FilePath::CharType kFileSystemDirectory[]; - - static const char kPersistentName[]; - static const char kTemporaryName[]; + fileapi::FileSystemPathManager* path_manager() { return path_manager_.get(); } private: - // Returns the storage identifier string for the given |url|. - static std::string GetStorageIdentifierFromURL(const GURL& url); - - const FilePath base_path_; - const bool is_incognito_; bool allow_file_access_from_files_; scoped_ptr<fileapi::FileSystemQuota> quota_manager_; + scoped_ptr<fileapi::FileSystemPathManager> path_manager_; DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemHostContext); }; diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 483d904..392b10f 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -31,7 +31,6 @@ #include "chrome/browser/extensions/extension_message_service.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" -#include "chrome/browser/file_system/file_system_host_context.h" #include "chrome/browser/gpu_process_host.h" #include "chrome/browser/history/history.h" #include "chrome/browser/io_thread.h" @@ -67,6 +66,7 @@ #include "ipc/ipc_platform_file.h" #include "ipc/ipc_switches.h" #include "media/base/media_switches.h" +#include "webkit/fileapi/file_system_path_manager.h" #include "webkit/glue/plugins/plugin_switches.h" #if defined(OS_WIN) @@ -233,7 +233,7 @@ BrowserRenderProcessHost::BrowserRenderProcessHost(Profile* profile) // requests them. ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile( id(), profile->GetPath().Append( - FileSystemHostContext::kFileSystemDirectory), + fileapi::FileSystemPathManager::kFileSystemDirectory), base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_OPEN_ALWAYS | diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 326655a..9179209 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1267,7 +1267,6 @@ 'browser/extensions/user_script_listener_unittest.cc', 'browser/extensions/user_script_master_unittest.cc', 'browser/file_path_watcher_unittest.cc', - 'browser/file_system/file_system_host_context_unittest.cc', 'browser/find_backend_unittest.cc', 'browser/first_run/first_run_unittest.cc', 'browser/geolocation/fake_access_token_store.h', diff --git a/tools/valgrind/memcheck/suppressions.txt b/tools/valgrind/memcheck/suppressions.txt index ead93ae..29f2a54 100644 --- a/tools/valgrind/memcheck/suppressions.txt +++ b/tools/valgrind/memcheck/suppressions.txt @@ -2851,18 +2851,6 @@ fun:_ZN11ProfileImpl18GetDownloadManagerEv } { - bug_58474_a - Memcheck:Leak - fun:_Znw* - fun:_ZN45FileSystemHostContextTest_CheckValidPath_Test8TestBodyEv -} -{ - bug_58474_b - Memcheck:Leak - fun:_Znw* - fun:_ZN42FileSystemHostContextTest_GetRootPath_Test8TestBodyEv -} -{ bug_58546 Memcheck:Leak fun:_Znw* diff --git a/webkit/fileapi/file_system_path_manager.cc b/webkit/fileapi/file_system_path_manager.cc new file mode 100644 index 0000000..12c273e --- /dev/null +++ b/webkit/fileapi/file_system_path_manager.cc @@ -0,0 +1,215 @@ +// 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/file_system_path_manager.h" + +#include "base/file_util.h" +#include "base/file_util_proxy.h" +#include "base/rand_util.h" +#include "base/logging.h" +#include "base/scoped_callback_factory.h" +#include "base/stringprintf.h" +#include "base/string_util.h" +#include "base/utf_string_conversions.h" +#include "googleurl/src/gurl.h" +#include "third_party/WebKit/WebKit/chromium/public/WebCString.h" +#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h" +#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h" +#include "webkit/glue/webkit_glue.h" + +// We use some of WebKit types for conversions between storage identifiers +// and origin URLs. +using WebKit::WebFileSystem; +using WebKit::WebSecurityOrigin; +using WebKit::WebString; + +using base::FileUtilProxy; +using base::PlatformFileError; + +namespace fileapi { + +const FilePath::CharType FileSystemPathManager::kFileSystemDirectory[] = + FILE_PATH_LITERAL("FileSystem"); + +const char FileSystemPathManager::kPersistentName[] = "Persistent"; +const char FileSystemPathManager::kTemporaryName[] = "Temporary"; + +namespace { + +// Restricted names. +// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions +static const char* const kRestrictedNames[] = { + "con", "prn", "aux", "nul", + "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9", + "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9", +}; + +// Restricted chars. +static const FilePath::CharType kRestrictedChars[] = { + '/', '\\', '<', '>', ':', '?', '*', '"', '|', +}; + +inline std::string FilePathStringToASCII( + const FilePath::StringType& path_string) { +#if defined(OS_WIN) + return WideToASCII(path_string); +#elif defined(OS_POSIX) + return path_string; +#endif +} + +} // anonymous namespace + +FileSystemPathManager::FileSystemPathManager( + const FilePath& data_path, + bool is_incognito, + bool allow_file_access_from_files) + : base_path_(data_path.Append(kFileSystemDirectory)), + is_incognito_(is_incognito), + allow_file_access_from_files_(allow_file_access_from_files) { +} + +bool FileSystemPathManager::GetFileSystemRootPath( + const GURL& origin_url, fileapi::FileSystemType type, + FilePath* root_path, std::string* name) const { + // TODO(kinuko): should return an isolated temporary file system space. + if (is_incognito_) + return false; + + if (!IsAllowedScheme(origin_url)) + return false; + + std::string storage_identifier = GetStorageIdentifierFromURL(origin_url); + switch (type) { + case fileapi::kFileSystemTypeTemporary: + if (root_path) + *root_path = base_path_.AppendASCII(storage_identifier) + .AppendASCII(kTemporaryName); + if (name) + *name = storage_identifier + ":" + kTemporaryName; + return true; + case fileapi::kFileSystemTypePersistent: + if (root_path) + *root_path = base_path_.AppendASCII(storage_identifier) + .AppendASCII(kPersistentName); + if (name) + *name = storage_identifier + ":" + kPersistentName; + return true; + } + LOG(WARNING) << "Unknown filesystem type is requested:" << type; + return false; +} + +bool FileSystemPathManager::CheckValidFileSystemPath( + const FilePath& path) const { + // Any paths that includes parent references are considered invalid. + if (path.ReferencesParent()) + return false; + + // The path should be a child of the profile FileSystem path. + FilePath relative; + if (!base_path_.AppendRelativePath(path, &relative)) + return false; + + // The relative path from the profile FileSystem path should at least + // contains two components, one for storage identifier and the other for type + + std::vector<FilePath::StringType> components; + relative.GetComponents(&components); + if (components.size() < 2) + return false; + + // The second component of the relative path to the root directory + // must be kPersistent or kTemporary. + if (!IsStringASCII(components[1])) + return false; + + std::string ascii_type_component = FilePathStringToASCII(components[1]); + if (ascii_type_component != kPersistentName && + ascii_type_component != kTemporaryName) + return false; + + return true; +} + +bool FileSystemPathManager::GetOriginFromPath( + const FilePath& path, GURL* origin_url) { + DCHECK(origin_url); + FilePath relative; + if (!base_path_.AppendRelativePath(path, &relative)) { + // The path should be a child of the profile's FileSystem path. + return false; + } + std::vector<FilePath::StringType> components; + relative.GetComponents(&components); + if (components.size() < 2) { + // The relative path should at least contain storage identifier and type. + return false; + } + WebSecurityOrigin web_security_origin = + WebSecurityOrigin::createFromDatabaseIdentifier( + webkit_glue::FilePathStringToWebString(components[0])); + *origin_url = GURL(web_security_origin.toString()); + + // We need this work-around for file:/// URIs as + // createFromDatabaseIdentifier returns empty origin_url for them. + if (allow_file_access_from_files_ && origin_url->spec().empty() && + components[0].find(FILE_PATH_LITERAL("file")) == 0) { + *origin_url = GURL("file:///"); + return true; + } + + return IsAllowedScheme(*origin_url); +} + +bool FileSystemPathManager::IsAllowedScheme(const GURL& url) const { + // Basically we only accept http or https. We allow file:// URLs + // only if --allow-file-access-from-files flag is given. + return url.SchemeIs("http") || url.SchemeIs("https") || + (url.SchemeIsFile() && allow_file_access_from_files_); +} + +bool FileSystemPathManager::IsRestrictedFileName( + const FilePath& filename) const { + if (filename.value().size() == 0) + return false; + + if (IsWhitespace(filename.value()[filename.value().size() - 1]) || + filename.value()[filename.value().size() - 1] == '.') + return true; + + std::string filename_lower = StringToLowerASCII( + FilePathStringToASCII(filename.value())); + + for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { + // Exact match. + if (filename_lower == kRestrictedNames[i]) + return true; + // Starts with "RESTRICTED_NAME.". + if (filename_lower.find(std::string(kRestrictedNames[i]) + ".") == 0) + return true; + } + + for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { + if (filename.value().find(kRestrictedChars[i]) != + FilePath::StringType::npos) + return true; + } + + return false; +} + +std::string FileSystemPathManager::GetStorageIdentifierFromURL( + const GURL& url) { + WebKit::WebSecurityOrigin web_security_origin = + WebKit::WebSecurityOrigin::createFromString(UTF8ToUTF16(url.spec())); + return web_security_origin.databaseIdentifier().utf8(); +} + +} // namespace fileapi + +COMPILE_ASSERT(int(WebFileSystem::TypeTemporary) == \ + int(fileapi::kFileSystemTypeTemporary), mismatching_enums); +COMPILE_ASSERT(int(WebFileSystem::TypePersistent) == \ + int(fileapi::kFileSystemTypePersistent), mismatching_enums); diff --git a/webkit/fileapi/file_system_path_manager.h b/webkit/fileapi/file_system_path_manager.h new file mode 100644 index 0000000..505a3c1 --- /dev/null +++ b/webkit/fileapi/file_system_path_manager.h @@ -0,0 +1,69 @@ +// 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. + +#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_PATH_MANAGER_H_ +#define WEBKIT_FILEAPI_FILE_SYSTEM_PATH_MANAGER_H_ + +#include <map> + +#include "base/callback.h" +#include "base/file_path.h" +#include "base/scoped_ptr.h" +#include "googleurl/src/gurl.h" +#include "webkit/fileapi/file_system_types.h" + +namespace fileapi { + +class FileSystemPathManager { + public: + FileSystemPathManager(const FilePath& data_path, + bool is_incognito, + bool allow_file_access_from_files); + + // Returns the root path and name for the file system specified by given + // |origin_url| and |type|. Returns true if the file system is available + // for the profile and |root_path| and |name| are filled successfully. + bool GetFileSystemRootPath(const GURL& origin_url, + fileapi::FileSystemType type, + FilePath* root_path, + std::string* name) const; + + // Checks if a given |path| is in the FileSystem base directory. + bool CheckValidFileSystemPath(const FilePath& path) const; + + // Retrieves the origin URL for the given |path| and populates + // |origin_url|. It returns false when the given |path| is not a + // valid filesystem path. + bool GetOriginFromPath(const FilePath& path, GURL* origin_url); + + // Returns true if the given |url|'s scheme is allowed to access + // filesystem. + bool IsAllowedScheme(const GURL& url) const; + + // Checks if a given |filename| contains any restricted names/chars in it. + bool IsRestrictedFileName(const FilePath& filename) const; + + // The FileSystem directory name. + static const FilePath::CharType kFileSystemDirectory[]; + + static const char kPersistentName[]; + static const char kTemporaryName[]; + + private: + class GetFileSystemRootPathTask; + friend class GetFileSystemRootPathTask; + + // Returns the storage identifier string for the given |url|. + static std::string GetStorageIdentifierFromURL(const GURL& url); + + const FilePath base_path_; + const bool is_incognito_; + bool allow_file_access_from_files_; + + DISALLOW_COPY_AND_ASSIGN(FileSystemPathManager); +}; + +} // namespace fileapi + +#endif // WEBKIT_FILEAPI_FILE_SYSTEM_PATH_MANAGER_H_ diff --git a/chrome/browser/file_system/file_system_host_context_unittest.cc b/webkit/fileapi/file_system_path_manager_unittest.cc index efc921e..1e67c3a 100644 --- a/chrome/browser/file_system/file_system_host_context_unittest.cc +++ b/webkit/fileapi/file_system_path_manager_unittest.cc @@ -2,14 +2,17 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "webkit/fileapi/file_system_path_manager.h" + #include "base/basictypes.h" #include "base/file_path.h" #include "base/scoped_ptr.h" #include "base/scoped_temp_dir.h" -#include "chrome/browser/file_system/file_system_host_context.h" #include "googleurl/src/gurl.h" #include "testing/gtest/include/gtest/gtest.h" +using fileapi::FileSystemPathManager; + namespace { // PS stands for path separator. @@ -126,41 +129,33 @@ const struct IsRestrictedNameTest { } // namespace -class FileSystemHostContextTest : public testing::Test { +class FileSystemPathManagerTest : public testing::Test { public: - FileSystemHostContextTest() - : io_thread_(BrowserThread::IO, &message_loop_), - data_path_(kTestDataPath) { - } - - void TearDown() { - message_loop_.RunAllPending(); - } - - ~FileSystemHostContextTest() { - message_loop_.RunAllPending(); + FileSystemPathManagerTest() + : data_path_(kTestDataPath) { } - scoped_refptr<FileSystemHostContext> GetHostContext(bool incognite) { - return new FileSystemHostContext(data_path_, incognite); + FileSystemPathManager* GetNewPathManager(bool incognito) { + path_manager_.reset(new FileSystemPathManager( + data_path_, incognito, false /* allow_file_access */)); + return path_manager_.get(); } private: - MessageLoopForIO message_loop_; - BrowserThread io_thread_; FilePath data_path_; + scoped_ptr<FileSystemPathManager> path_manager_; }; -TEST_F(FileSystemHostContextTest, GetRootPath) { +TEST_F(FileSystemPathManagerTest, GetRootPath) { for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kRootPathTestCases); ++i) { SCOPED_TRACE(testing::Message() << "RootPath #" << i << " " << kRootPathTestCases[i].expected_path); - scoped_refptr<FileSystemHostContext> context = GetHostContext( + FileSystemPathManager* manager = GetNewPathManager( kRootPathTestCases[i].off_the_record); FilePath root_path; - bool result = context->GetFileSystemRootPath( + bool result = manager->GetFileSystemRootPath( GURL(kRootPathTestCases[i].origin_url), kRootPathTestCases[i].type, &root_path, NULL); @@ -173,21 +168,21 @@ TEST_F(FileSystemHostContextTest, GetRootPath) { } } -TEST_F(FileSystemHostContextTest, CheckValidPath) { - scoped_refptr<FileSystemHostContext> context = GetHostContext(false); +TEST_F(FileSystemPathManagerTest, CheckValidPath) { + FileSystemPathManager* manager = GetNewPathManager(false); FilePath root_path; - EXPECT_TRUE(context->GetFileSystemRootPath( + EXPECT_TRUE(manager->GetFileSystemRootPath( GURL("http://foo.com/"), fileapi::kFileSystemTypePersistent, &root_path, NULL)); // The root path must be valid, but upper directories or directories // that are not in our temporary or persistent directory must be // evaluated invalid. - EXPECT_TRUE(context->CheckValidFileSystemPath(root_path)); - EXPECT_FALSE(context->CheckValidFileSystemPath(root_path.DirName())); - EXPECT_FALSE(context->CheckValidFileSystemPath( + EXPECT_TRUE(manager->CheckValidFileSystemPath(root_path)); + EXPECT_FALSE(manager->CheckValidFileSystemPath(root_path.DirName())); + EXPECT_FALSE(manager->CheckValidFileSystemPath( root_path.DirName().DirName())); - EXPECT_FALSE(context->CheckValidFileSystemPath( + EXPECT_FALSE(manager->CheckValidFileSystemPath( root_path.DirName().AppendASCII("ArbitraryName"))); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCheckValidPathTestCases); ++i) { @@ -197,17 +192,17 @@ TEST_F(FileSystemHostContextTest, CheckValidPath) { if (!path.IsAbsolute()) path = root_path.Append(path); EXPECT_EQ(kCheckValidPathTestCases[i].expected_valid, - context->CheckValidFileSystemPath(path)); + manager->CheckValidFileSystemPath(path)); } } -TEST_F(FileSystemHostContextTest, IsRestrictedName) { - scoped_refptr<FileSystemHostContext> context = GetHostContext(false); +TEST_F(FileSystemPathManagerTest, IsRestrictedName) { + FileSystemPathManager* manager = GetNewPathManager(false); for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kIsRestrictedNameTestCases); ++i) { SCOPED_TRACE(testing::Message() << "IsRestrictedName #" << i << " " << kIsRestrictedNameTestCases[i].name); FilePath name(kIsRestrictedNameTestCases[i].name); EXPECT_EQ(kIsRestrictedNameTestCases[i].expected_dangerous, - context->IsRestrictedFileName(name)); + manager->IsRestrictedFileName(name)); } } diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi index f01e9db..5189564 100644 --- a/webkit/fileapi/webkit_fileapi.gypi +++ b/webkit/fileapi/webkit_fileapi.gypi @@ -17,6 +17,8 @@ 'file_system_callback_dispatcher.h', 'file_system_operation.cc', 'file_system_operation.h', + 'file_system_path_manager.cc', + 'file_system_path_manager.h', 'file_system_quota.cc', 'file_system_quota.h', 'file_system_types.h', diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi index b55681d..14b7386 100644 --- a/webkit/tools/test_shell/test_shell.gypi +++ b/webkit/tools/test_shell/test_shell.gypi @@ -376,6 +376,7 @@ '../../database/database_util_unittest.cc', '../../database/quota_table_unittest.cc', '../../fileapi/file_system_operation_unittest.cc', + '../../fileapi/file_system_path_manager_unittest.cc', '../../fileapi/file_system_quota_unittest.cc', '../../glue/bookmarklet_unittest.cc', '../../glue/context_menu_unittest.cc', |