summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-12 06:15:43 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-12 06:15:43 +0000
commiteafe2e7b3164af96be59ff2e76bc90e9c113790b (patch)
treed98279db131c2455dcd7d7ac6323a2fcca471402
parent9e0315287c149e48fb31d15a121699898c917b0b (diff)
downloadchromium_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.cc10
-rw-r--r--chrome/browser/file_system/file_system_host_context.cc193
-rw-r--r--chrome/browser/file_system/file_system_host_context.h40
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc4
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--tools/valgrind/memcheck/suppressions.txt12
-rw-r--r--webkit/fileapi/file_system_path_manager.cc215
-rw-r--r--webkit/fileapi/file_system_path_manager.h69
-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.gypi2
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
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',