diff options
author | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 22:01:51 +0000 |
---|---|---|
committer | tbarzic@chromium.org <tbarzic@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-01-24 22:01:51 +0000 |
commit | 5b7e42e6e9ee09a5fa0b93b6bf3d7339c1db2b0f (patch) | |
tree | 5a93d1a57760e029fcfc36db69a036421ff04079 | |
parent | 33c1c26ae20ac8b60ce78945ad016a277d2b10ec (diff) | |
download | chromium_src-5b7e42e6e9ee09a5fa0b93b6bf3d7339c1db2b0f.zip chromium_src-5b7e42e6e9ee09a5fa0b93b6bf3d7339c1db2b0f.tar.gz chromium_src-5b7e42e6e9ee09a5fa0b93b6bf3d7339c1db2b0f.tar.bz2 |
New FileSystemURL cracking
follow up on https://codereview.chromium.org/11648027/
Instead of cracking FileSystemURL in its ctor (somewhat magically, using singleton IsolatedContext and SystemExternalMountPoints), require FileSystemURL to be cracked explicitly.
The FileSystemURL can be cracked using specific MountPoints implementation or using specific FileSystemContext which will select available MountPoints implementation that should be used to crack the url.
(CrackURL/CreateCrackedFileSystemURL methods).
Modify FileSystemURL usages to use new cracking methods.
BUG=158837
TEST=content_unittests: IsolatedContextTest.* ExternalMountPointsTest.* FileSystemContextTest.*
Review URL: https://chromiumcodereview.appspot.com/11787028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@178664 0039d316-1c4b-4281-b951-d872f2087c98
50 files changed, 1318 insertions, 398 deletions
diff --git a/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc b/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc index d5481e1..7a0539a 100644 --- a/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc +++ b/chrome/browser/browsing_data/browsing_data_file_system_helper_unittest.cc @@ -174,7 +174,7 @@ class BrowsingDataFileSystemHelperTest : public testing::Test { void CreateDirectoryForOriginAndType(const GURL& origin, fileapi::FileSystemType type) { FilePath target = sandbox_->GetFileSystemRootPathOnFileThread( - fileapi::FileSystemURL(origin, type, FilePath()), true); + fileapi::FileSystemURL::CreateForTest(origin, type, FilePath()), true); EXPECT_TRUE(file_util::DirectoryExists(target)); } diff --git a/chrome/browser/chromeos/drive/drive_task_executor.cc b/chrome/browser/chromeos/drive/drive_task_executor.cc index dd2bcd5..8ce2e94 100644 --- a/chrome/browser/chromeos/drive/drive_task_executor.cc +++ b/chrome/browser/chromeos/drive/drive_task_executor.cc @@ -26,9 +26,10 @@ #include "webkit/fileapi/file_system_url.h" #include "webkit/fileapi/file_system_util.h" -namespace drive { - using file_handler_util::FileTaskExecutor; +using fileapi::FileSystemURL; + +namespace drive { DriveTaskExecutor::DriveTaskExecutor(Profile* profile, const std::string& app_id, @@ -43,15 +44,14 @@ DriveTaskExecutor::~DriveTaskExecutor() { } bool DriveTaskExecutor::ExecuteAndNotify( - const std::vector<GURL>& file_urls, + const std::vector<FileSystemURL>& file_urls, const file_handler_util::FileTaskFinishedCallback& done) { std::vector<FilePath> raw_paths; - for (std::vector<GURL>::const_iterator iter = file_urls.begin(); - iter != file_urls.end(); ++iter) { - fileapi::FileSystemURL url(*iter); - if (!url.is_valid() || url.type() != fileapi::kFileSystemTypeDrive) + for (std::vector<FileSystemURL>::const_iterator url = file_urls.begin(); + url != file_urls.end(); ++url) { + if (!url->is_valid() || url->type() != fileapi::kFileSystemTypeDrive) return false; - raw_paths.push_back(url.virtual_path()); + raw_paths.push_back(url->virtual_path()); } DriveSystemService* system_service = diff --git a/chrome/browser/chromeos/drive/drive_task_executor.h b/chrome/browser/chromeos/drive/drive_task_executor.h index 9d7eeba..f415127 100644 --- a/chrome/browser/chromeos/drive/drive_task_executor.h +++ b/chrome/browser/chromeos/drive/drive_task_executor.h @@ -25,7 +25,7 @@ class DriveTaskExecutor : public file_handler_util::FileTaskExecutor { public: // FileTaskExecutor overrides virtual bool ExecuteAndNotify( - const std::vector<GURL>& file_urls, + const std::vector<fileapi::FileSystemURL>& file_urls, const file_handler_util::FileTaskFinishedCallback& done) OVERRIDE; private: diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api.cc b/chrome/browser/chromeos/extensions/file_browser_private_api.cc index d6ed5d8..7a54014 100644 --- a/chrome/browser/chromeos/extensions/file_browser_private_api.cc +++ b/chrome/browser/chromeos/extensions/file_browser_private_api.cc @@ -95,6 +95,7 @@ using content::WebContents; using extensions::Extension; using extensions::ZipFileCreator; using file_handler_util::FileTaskExecutor; +using fileapi::FileSystemURL; using google_apis::InstalledApp; namespace { @@ -327,8 +328,9 @@ void GetSizeStatsOnFileThread(const std::string& mount_path, // isn't of the type CrosMountPointProvider handles, return an empty FilePath. // // Virtual paths will look like "Downloads/foo/bar.txt" or "drive/foo/bar.txt". -FilePath GetVirtualPathFromURL(const GURL& url) { - fileapi::FileSystemURL filesystem_url(url); +FilePath GetVirtualPathFromURL(fileapi::FileSystemContext* context, + const GURL& url) { + fileapi::FileSystemURL filesystem_url(context->CrackURL(url)); if (!chromeos::CrosMountPointProvider::CanHandleURL(filesystem_url)) return FilePath(); return filesystem_url.virtual_path(); @@ -339,26 +341,28 @@ FilePath GetVirtualPathFromURL(const GURL& url) { // // Local paths will look like "/home/chronos/user/Downloads/foo/bar.txt" or // "/special/drive/foo/bar.txt". -FilePath GetLocalPathFromURL(const GURL& url) { - fileapi::FileSystemURL filesystem_url(url); +FilePath GetLocalPathFromURL(fileapi::FileSystemContext* context, + const GURL& url) { + fileapi::FileSystemURL filesystem_url(context->CrackURL(url)); if (!chromeos::CrosMountPointProvider::CanHandleURL(filesystem_url)) return FilePath(); return filesystem_url.path(); } // Make a set of unique filename suffixes out of the list of file URLs. -std::set<std::string> GetUniqueSuffixes(base::ListValue* file_url_list) { +std::set<std::string> GetUniqueSuffixes(base::ListValue* file_url_list, + fileapi::FileSystemContext* context) { std::set<std::string> suffixes; for (size_t i = 0; i < file_url_list->GetSize(); ++i) { - std::string url; - if (!file_url_list->GetString(i, &url)) + std::string url_str; + if (!file_url_list->GetString(i, &url_str)) return std::set<std::string>(); - FilePath path = GetVirtualPathFromURL(GURL(url)); - if (path.empty()) + FileSystemURL url = context->CrackURL(GURL(url_str)); + if (!url.is_valid() || url.path().empty()) return std::set<std::string>(); // We'll skip empty suffixes. - if (!path.Extension().empty()) - suffixes.insert(path.Extension()); + if (!url.path().Extension().empty()) + suffixes.insert(url.path().Extension()); } return suffixes; } @@ -441,6 +445,30 @@ void FillDriveFilePropertiesValue( file_specific_info.content_mime_type()); } +void GetMimeTypesForFileURLs(const std::vector<FilePath>& file_paths, + std::set<std::string>* mime_types) { + for (std::vector<FilePath>::const_iterator iter = file_paths.begin(); + iter != file_paths.end(); ++iter) { + const FilePath::StringType file_extension = + StringToLowerASCII(iter->Extension()); + + // TODO(thorogood): Rearchitect this call so it can run on the File thread; + // GetMimeTypeFromFile requires this on Linux. Right now, we use + // Chrome-level knowledge only. + std::string mime_type; + if (file_extension.empty() || + !net::GetWellKnownMimeTypeFromExtension(file_extension.substr(1), + &mime_type)) { + // If the file doesn't have an extension or its mime-type cannot be + // determined, then indicate that it has the empty mime-type. This will + // only be matched if the Web Intents accepts "*" or "*/*". + mime_types->insert(""); + } else { + mime_types->insert(mime_type); + } + } +} + } // namespace class RequestLocalFileSystemFunction::LocalFileSystemCallbackDispatcher { @@ -674,7 +702,12 @@ bool FileWatchBrowserFunctionBase::RunImpl() { if (!args_->GetString(0, &url) || url.empty()) return false; - GURL file_watch_url(url); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FileSystemURL file_watch_url = file_system_context->CrackURL(GURL(url)); BrowserThread::PostTask( BrowserThread::FILE, FROM_HERE, base::Bind( @@ -689,9 +722,9 @@ bool FileWatchBrowserFunctionBase::RunImpl() { void FileWatchBrowserFunctionBase::RunFileWatchOperationOnFileThread( scoped_refptr<FileBrowserEventRouter> event_router, - const GURL& file_url, const std::string& extension_id) { - FilePath local_path = GetLocalPathFromURL(file_url); - FilePath virtual_path = GetVirtualPathFromURL(file_url); + const FileSystemURL& file_url, const std::string& extension_id) { + FilePath local_path = file_url.path(); + FilePath virtual_path = file_url.virtual_path(); bool result = !local_path.empty() && PerformFileWatchOperation( event_router, local_path, virtual_path, extension_id); @@ -876,40 +909,16 @@ bool GetFileTasksFileBrowserFunction::FindDriveAppTasks( return true; } -static void GetMimeTypesForFileURLs(const std::vector<GURL>& file_urls, - std::set<std::string>* mime_types) { - for (std::vector<GURL>::const_iterator iter = file_urls.begin(); - iter != file_urls.end(); ++iter) { - const FilePath file = FilePath(GURL(iter->spec()).ExtractFileName()); - const FilePath::StringType file_extension = - StringToLowerASCII(file.Extension()); - - // TODO(thorogood): Rearchitect this call so it can run on the File thread; - // GetMimeTypeFromFile requires this on Linux. Right now, we use - // Chrome-level knowledge only. - std::string mime_type; - if (file_extension.empty() || !net::GetWellKnownMimeTypeFromExtension( - file_extension.substr(1), &mime_type)) { - // If the file doesn't have an extension or its mime-type cannot be - // determined, then indicate that it has the empty mime-type. This will - // only be matched if the Web Intents accepts "*" or "*/*". - mime_types->insert(""); - } else { - mime_types->insert(mime_type); - } - } -} - bool GetFileTasksFileBrowserFunction::FindAppTasks( - const std::vector<GURL>& file_urls, + const std::vector<FilePath>& file_paths, ListValue* result_list) { - DCHECK(!file_urls.empty()); + DCHECK(!file_paths.empty()); ExtensionService* service = profile_->GetExtensionService(); if (!service) return false; std::set<std::string> mime_types; - GetMimeTypesForFileURLs(file_urls, &mime_types); + GetMimeTypesForFileURLs(file_paths, &mime_types); for (ExtensionSet::const_iterator iter = service->extensions()->begin(); iter != service->extensions()->end(); @@ -958,15 +967,15 @@ bool GetFileTasksFileBrowserFunction::FindAppTasks( // Find Web Intent platform apps that support the View task, and add them to // the |result_list|. These will be marked as kTaskWebIntent. bool GetFileTasksFileBrowserFunction::FindWebIntentTasks( - const std::vector<GURL>& file_urls, + const std::vector<FilePath>& file_paths, ListValue* result_list) { - DCHECK(!file_urls.empty()); + DCHECK(!file_paths.empty()); ExtensionService* service = profile_->GetExtensionService(); if (!service) return false; std::set<std::string> mime_types; - GetMimeTypesForFileURLs(file_urls, &mime_types); + GetMimeTypesForFileURLs(file_paths, &mime_types); for (ExtensionSet::const_iterator iter = service->extensions()->begin(); iter != service->extensions()->end(); @@ -1023,24 +1032,37 @@ bool GetFileTasksFileBrowserFunction::RunImpl() { mime_types_list->GetSize() != 0) return false; + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + // Collect all the URLs, convert them to GURLs, and crack all the urls into // file paths. FileInfoList info_list; std::vector<GURL> file_urls; + std::vector<FilePath> file_paths; for (size_t i = 0; i < files_list->GetSize(); ++i) { FileInfo info; - std::string file_url; - if (!files_list->GetString(i, &file_url)) + std::string file_url_str; + if (!files_list->GetString(i, &file_url_str)) return false; - info.file_url = GURL(file_url); - file_urls.push_back(info.file_url); + if (mime_types_list->GetSize() != 0 && !mime_types_list->GetString(i, &info.mime_type)) return false; - fileapi::FileSystemURL file_system_url(info.file_url); - if (chromeos::CrosMountPointProvider::CanHandleURL(file_system_url)) { - info.file_path = file_system_url.path(); - } + + GURL file_url(file_url_str); + fileapi::FileSystemURL file_system_url( + file_system_context->CrackURL(file_url)); + if (!chromeos::CrosMountPointProvider::CanHandleURL(file_system_url)) + continue; + + file_urls.push_back(file_url); + file_paths.push_back(file_system_url.path()); + + info.file_url = file_url; + info.file_path = file_system_url.path(); info_list.push_back(info); } @@ -1063,7 +1085,7 @@ bool GetFileTasksFileBrowserFunction::RunImpl() { std::set<const FileBrowserHandler*> default_tasks; if (!file_handler_util::FindCommonTasks(profile_, file_urls, &common_tasks)) return false; - file_handler_util::FindDefaultTasks(profile_, file_urls, + file_handler_util::FindDefaultTasks(profile_, file_paths, common_tasks, &default_tasks); ExtensionService* service = @@ -1106,12 +1128,12 @@ bool GetFileTasksFileBrowserFunction::RunImpl() { // apps may accept, and all previous Drive and extension tasks. As above, we // know there aren't duplicates because they're entirely different kinds of // tasks. - if (!FindAppTasks(file_urls, result_list)) + if (!FindAppTasks(file_paths, result_list)) return false; // TODO(benwells): remove the web intents tasks once we no longer support // them. - if (!FindWebIntentTasks(file_urls, result_list)) + if (!FindWebIntentTasks(file_paths, result_list)) return false; if (VLOG_IS_ON(1)) { @@ -1163,14 +1185,24 @@ bool ExecuteTasksFileBrowserFunction::RunImpl() { if (!files_list->GetSize()) return true; - std::vector<GURL> file_urls; + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + std::vector<FileSystemURL> file_urls; for (size_t i = 0; i < files_list->GetSize(); i++) { - std::string origin_file_url; - if (!files_list->GetString(i, &origin_file_url)) { + std::string file_url_str; + if (!files_list->GetString(i, &file_url_str)) { error_ = kInvalidFileUrl; return false; } - file_urls.push_back(GURL(origin_file_url)); + FileSystemURL url = file_system_context->CrackURL(GURL(file_url_str)); + if (!chromeos::CrosMountPointProvider::CanHandleURL(url)) { + error_ = kInvalidFileUrl; + return false; + } + file_urls.push_back(url); } WebContents* web_contents = @@ -1210,7 +1242,13 @@ bool SetDefaultTaskFileBrowserFunction::RunImpl() { base::ListValue* file_url_list; if (!args_->GetList(1, &file_url_list)) return false; - std::set<std::string> suffixes = GetUniqueSuffixes(file_url_list); + + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + std::set<std::string> suffixes = GetUniqueSuffixes(file_url_list, context); // MIME types are an optional parameter. base::ListValue* mime_type_list; @@ -1331,7 +1369,7 @@ void FileBrowserFunction::GetLocalPathsOnFileThread( } // Extract the path from |file_url|. - fileapi::FileSystemURL url(file_url); + fileapi::FileSystemURL url(file_system_context->CrackURL(file_url)); if (!chromeos::CrosMountPointProvider::CanHandleURL(url)) continue; @@ -1395,11 +1433,17 @@ bool ViewFilesFunction::RunImpl() { std::string internal_task_id; args_->GetString(1, &internal_task_id); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + std::vector<FilePath> files; for (size_t i = 0; i < path_list->GetSize(); ++i) { std::string url_as_string; path_list->GetString(i, &url_as_string); - FilePath path = GetLocalPathFromURL(GURL(url_as_string)); + FilePath path = GetLocalPathFromURL(file_system_context, + GURL(url_as_string)); if (path.empty()) return false; files.push_back(path); @@ -1672,7 +1716,13 @@ void SetLastModifiedFunction::RunOperationOnFileThread(std::string file_url, time_t timestamp) { bool succeeded = false; - FilePath local_path = GetLocalPathFromURL(GURL(file_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath local_path = GetLocalPathFromURL(file_system_context, + GURL(file_url)); if (!local_path.empty()) { struct stat sb; if (stat(local_path.value().c_str(), &sb) == 0) { @@ -1708,7 +1758,13 @@ bool GetSizeStatsFunction::RunImpl() { if (!args_->GetString(0, &mount_url)) return false; - FilePath file_path = GetLocalPathFromURL(GURL(mount_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath file_path = GetLocalPathFromURL(file_system_context, + GURL(mount_url)); if (file_path.empty()) return false; @@ -1804,7 +1860,13 @@ bool FormatDeviceFunction::RunImpl() { return false; } - FilePath file_path = GetLocalPathFromURL(GURL(volume_file_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath file_path = GetLocalPathFromURL(file_system_context, + GURL(volume_file_url)); if (file_path.empty()) return false; @@ -1831,7 +1893,13 @@ bool GetVolumeMetadataFunction::RunImpl() { return false; } - FilePath file_path = GetLocalPathFromURL(GURL(volume_mount_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath file_path = GetLocalPathFromURL(file_system_context, + GURL(volume_mount_url)); if (file_path.empty()) { error_ = "Invalid mount path."; return false; @@ -2281,10 +2349,16 @@ void GetDriveFilePropertiesFunction::GetNextFileProperties() { return; } + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + std::string file_str; path_list_->GetString(current_index_, &file_str); GURL file_url = GURL(file_str); - FilePath file_path = GetVirtualPathFromURL(file_url); + FilePath file_path = GetVirtualPathFromURL(file_system_context, + file_url); base::DictionaryValue* property_dict = new base::DictionaryValue; property_dict->SetString("fileUrl", file_url.spec()); @@ -2502,6 +2576,11 @@ bool GetFileLocationsFunction::RunImpl() { if (!args_->GetList(0, &file_urls_as_strings)) return false; + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + // Convert the list of strings to a list of GURLs. scoped_ptr<ListValue> locations(new ListValue); for (size_t i = 0; i < file_urls_as_strings->GetSize(); ++i) { @@ -2509,7 +2588,8 @@ bool GetFileLocationsFunction::RunImpl() { if (!file_urls_as_strings->GetString(i, &file_url_as_string)) return false; - fileapi::FileSystemURL url((GURL(file_url_as_string))); + fileapi::FileSystemURL url( + file_system_context->CrackURL(GURL(file_url_as_string))); if (url.type() == fileapi::kFileSystemTypeDrive) locations->Append(new base::StringValue("drive")); else @@ -2665,12 +2745,18 @@ bool CancelFileTransfersFunction::RunImpl() { if (!system_service) return false; + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + scoped_ptr<ListValue> responses(new ListValue()); for (size_t i = 0; i < url_list->GetSize(); ++i) { std::string url_as_string; url_list->GetString(i, &url_as_string); - FilePath file_path = GetLocalPathFromURL(GURL(url_as_string)); + FilePath file_path = GetLocalPathFromURL(file_system_context, + GURL(url_as_string)); if (file_path.empty()) continue; @@ -2712,8 +2798,15 @@ bool TransferFileFunction::RunImpl() { if (!system_service) return false; - FilePath source_file = GetLocalPathFromURL(GURL(source_file_url)); - FilePath destination_file = GetLocalPathFromURL(GURL(destination_file_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath source_file = GetLocalPathFromURL(file_system_context, + GURL(source_file_url)); + FilePath destination_file = GetLocalPathFromURL(file_system_context, + GURL(destination_file_url)); if (source_file.empty() || destination_file.empty()) return false; @@ -2961,7 +3054,13 @@ bool RequestDirectoryRefreshFunction::RunImpl() { if (!system_service || !system_service->file_system()) return false; - FilePath directory_path = GetVirtualPathFromURL(GURL(file_url_as_string)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath directory_path = GetVirtualPathFromURL(file_system_context, + GURL(file_url_as_string)); system_service->file_system()->RequestDirectoryRefresh(directory_path); return true; @@ -2983,7 +3082,13 @@ bool ZipSelectionFunction::RunImpl() { if (!args_->GetString(0, &dir_url) || dir_url.empty()) return false; - FilePath src_dir = GetLocalPathFromURL(GURL(dir_url)); + content::SiteInstance* site_instance = render_view_host()->GetSiteInstance(); + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition(profile(), site_instance)-> + GetFileSystemContext(); + + FilePath src_dir = GetLocalPathFromURL(file_system_context, + GURL(dir_url)); if (src_dir.empty()) return false; @@ -2997,7 +3102,7 @@ bool ZipSelectionFunction::RunImpl() { for (size_t i = 0; i < selection_urls->GetSize(); ++i) { std::string file_url; selection_urls->GetString(i, &file_url); - FilePath path = GetLocalPathFromURL(GURL(file_url)); + FilePath path = GetLocalPathFromURL(file_system_context, GURL(file_url)); if (path.empty()) return false; files.push_back(path); diff --git a/chrome/browser/chromeos/extensions/file_browser_private_api.h b/chrome/browser/chromeos/extensions/file_browser_private_api.h index d6bfcbd..d629068 100644 --- a/chrome/browser/chromeos/extensions/file_browser_private_api.h +++ b/chrome/browser/chromeos/extensions/file_browser_private_api.h @@ -29,6 +29,7 @@ class Value; namespace fileapi { class FileSystemContext; +class FileSystemURL; } namespace drive { @@ -103,7 +104,7 @@ class FileWatchBrowserFunctionBase : public AsyncExtensionFunction { void RespondOnUIThread(bool success); void RunFileWatchOperationOnFileThread( scoped_refptr<FileBrowserEventRouter> event_router, - const GURL& file_url, + const fileapi::FileSystemURL& file_url, const std::string& extension_id); }; @@ -199,12 +200,12 @@ class GetFileTasksFileBrowserFunction : public AsyncExtensionFunction { // Find the list of Web Intent tasks that can be used with the given file // types, appending them to the |result_list|. - bool FindWebIntentTasks(const std::vector<GURL>& file_urls, + bool FindWebIntentTasks(const std::vector<FilePath>& file_paths, ListValue* result_list); // Find the list of app file handlers that can be used with the given file // types, appending them to the |result_list|. - bool FindAppTasks(const std::vector<GURL>& file_urls, + bool FindAppTasks(const std::vector<FilePath>& file_paths, ListValue* result_list); }; diff --git a/chrome/browser/chromeos/extensions/file_handler_util.cc b/chrome/browser/chromeos/extensions/file_handler_util.cc index dc5aa72..b6b56e4 100644 --- a/chrome/browser/chromeos/extensions/file_handler_util.cc +++ b/chrome/browser/chromeos/extensions/file_handler_util.cc @@ -49,6 +49,7 @@ using content::ChildProcessSecurityPolicy; using content::SiteInstance; using content::WebContents; using extensions::Extension; +using fileapi::FileSystemURL; namespace file_handler_util { @@ -347,27 +348,19 @@ FileBrowserHandlerSet::iterator FindHandler( // Given the list of selected files, returns array of file action tasks // that are shared between them. void FindDefaultTasks(Profile* profile, - const std::vector<GURL>& files_list, + const std::vector<FilePath>& files_list, const FileBrowserHandlerSet& common_tasks, FileBrowserHandlerSet* default_tasks) { DCHECK(default_tasks); default_tasks->clear(); std::set<std::string> default_ids; - for (std::vector<GURL>::const_iterator it = files_list.begin(); + for (std::vector<FilePath>::const_iterator it = files_list.begin(); it != files_list.end(); ++it) { - // Get the default task for this file based only on the extension (since - // we don't have MIME types here), and add it to the set of default tasks. - fileapi::FileSystemURL filesystem_url(*it); - if (filesystem_url.is_valid() && - (filesystem_url.type() == fileapi::kFileSystemTypeDrive || - filesystem_url.type() == fileapi::kFileSystemTypeNativeMedia || - filesystem_url.type() == fileapi::kFileSystemTypeNativeLocal)) { - std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs( - profile, "", filesystem_url.virtual_path().Extension()); - if (!task_id.empty()) - default_ids.insert(task_id); - } + std::string task_id = file_handler_util::GetDefaultTaskIdFromPrefs( + profile, "", it->Extension()); + if (!task_id.empty()) + default_ids.insert(task_id); } const FileBrowserHandler* builtin_task = NULL; @@ -454,8 +447,10 @@ bool FindCommonTasks(Profile* profile, return true; } -bool GetTaskForURL( - Profile* profile, const GURL& url, const FileBrowserHandler** handler) { +bool GetTaskForURLAndPath(Profile* profile, + const GURL& url, + const FilePath& file_path, + const FileBrowserHandler** handler) { std::vector<GURL> file_urls; file_urls.push_back(url); @@ -467,7 +462,10 @@ bool GetTaskForURL( if (common_tasks.empty()) return false; - FindDefaultTasks(profile, file_urls, common_tasks, &default_tasks); + std::vector<FilePath> file_paths; + file_paths.push_back(file_path); + + FindDefaultTasks(profile, file_paths, common_tasks, &default_tasks); // If there's none, or more than one, then we don't have a canonical default. if (!default_tasks.empty()) { @@ -488,7 +486,7 @@ bool GetTaskForURL( class ExtensionTaskExecutor : public FileTaskExecutor { public: // FileTaskExecutor overrides. - virtual bool ExecuteAndNotify(const std::vector<GURL>& file_urls, + virtual bool ExecuteAndNotify(const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) OVERRIDE; private: @@ -507,7 +505,6 @@ class ExtensionTaskExecutor : public FileTaskExecutor { FileDefinition(); ~FileDefinition(); - GURL target_file_url; FilePath virtual_path; FilePath absolute_path; bool is_directory; @@ -520,7 +517,7 @@ class ExtensionTaskExecutor : public FileTaskExecutor { const GURL& handler_base_url, const scoped_refptr<const extensions::Extension>& handler, int handler_pid, - const std::vector<GURL>& file_urls); + const std::vector<FileSystemURL>& file_urls); void ExecuteDoneOnUIThread(bool success); void ExecuteFileActionsOnUIThread(const std::string& file_system_name, @@ -548,7 +545,7 @@ class ExtensionTaskExecutor : public FileTaskExecutor { class WebIntentTaskExecutor : public FileTaskExecutor { public: // FileTaskExecutor overrides. - virtual bool ExecuteAndNotify(const std::vector<GURL>& file_urls, + virtual bool ExecuteAndNotify(const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) OVERRIDE; private: @@ -569,7 +566,7 @@ class WebIntentTaskExecutor : public FileTaskExecutor { class AppTaskExecutor : public FileTaskExecutor { public: // FileTaskExecutor overrides. - virtual bool ExecuteAndNotify(const std::vector<GURL>& file_urls, + virtual bool ExecuteAndNotify(const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) OVERRIDE; private: @@ -639,12 +636,12 @@ FileTaskExecutor::FileTaskExecutor(Profile* profile, FileTaskExecutor::~FileTaskExecutor() { } -bool FileTaskExecutor::Execute(const std::vector<GURL>& file_urls) { +bool FileTaskExecutor::Execute(const std::vector<FileSystemURL>& file_urls) { return ExecuteAndNotify(file_urls, FileTaskFinishedCallback()); } bool FileTaskExecutor::FileBrowserHasAccessPermissionForFiles( - const std::vector<GURL>& files) { + const std::vector<FileSystemURL>& files) { // Check if the file browser extension has permissions for the files in its // file system context. GURL site = extensions::ExtensionSystem::Get(profile())->extension_service()-> @@ -657,13 +654,12 @@ bool FileTaskExecutor::FileBrowserHasAccessPermissionForFiles( return false; for (size_t i = 0; i < files.size(); ++i) { - fileapi::FileSystemURL url(files[i]); // Make sure this url really being used by the right caller extension. - if (source_url_.GetOrigin() != url.origin()) + if (source_url_.GetOrigin() != files[i].origin()) return false; - if (!chromeos::CrosMountPointProvider::CanHandleURL(url) || - !external_provider->IsAccessAllowed(url)) { + if (!chromeos::CrosMountPointProvider::CanHandleURL(files[i]) || + !external_provider->IsAccessAllowed(files[i])) { return false; } } @@ -702,7 +698,7 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { scoped_refptr<const Extension> handler_extension, int handler_pid, const std::string& action_id, - const std::vector<GURL>& file_urls) { + const std::vector<FileSystemURL>& file_urls) { return base::Bind( &ExecuteTasksFileSystemCallbackDispatcher::DidOpenFileSystem, base::Owned(new ExecuteTasksFileSystemCallbackDispatcher( @@ -719,8 +715,8 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { } DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); ExtensionTaskExecutor::FileDefinitionList file_list; - for (std::vector<GURL>::iterator iter = origin_file_urls_.begin(); - iter != origin_file_urls_.end(); + for (std::vector<FileSystemURL>::iterator iter = urls_.begin(); + iter != urls_.end(); ++iter) { // Set up file permission access. ExtensionTaskExecutor::FileDefinition file; @@ -765,19 +761,19 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { const scoped_refptr<const Extension>& handler_extension, int handler_pid, const std::string& action_id, - const std::vector<GURL>& file_urls) + const std::vector<FileSystemURL>& file_urls) : executor_(executor), file_system_context_handler_(file_system_context_handler), handler_extension_(handler_extension), handler_pid_(handler_pid), action_id_(action_id), - origin_file_urls_(file_urls) { + urls_(file_urls) { DCHECK(executor_); } // Checks legitimacy of file url and grants file RO access permissions from // handler (target) extension and its renderer process. - bool SetupFileAccessPermissions(const GURL& origin_file_url, + bool SetupFileAccessPermissions(const FileSystemURL& url, FileDefinition* file) { if (!handler_extension_.get()) return false; @@ -785,8 +781,6 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { if (handler_pid_ == 0) return false; - fileapi::FileSystemURL url(origin_file_url); - fileapi::ExternalFileSystemMountPointProvider* external_provider_handler = file_system_context_handler_->external_provider(); @@ -816,11 +810,6 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { handler_extension_->id(), virtual_path); // Output values. - GURL target_origin_url(Extension::GetBaseURLFromExtensionId( - handler_extension_->id())); - GURL base_url = fileapi::GetFileSystemRootURI(target_origin_url, - fileapi::kFileSystemTypeExternal); - file->target_file_url = GURL(base_url.spec() + virtual_path.value()); file->virtual_path = virtual_path; file->is_directory = file_info.is_directory; file->absolute_path = local_path; @@ -832,7 +821,7 @@ class ExtensionTaskExecutor::ExecuteTasksFileSystemCallbackDispatcher { scoped_refptr<const Extension> handler_extension_; int handler_pid_; std::string action_id_; - std::vector<GURL> origin_file_urls_; + std::vector<FileSystemURL> urls_; DISALLOW_COPY_AND_ASSIGN(ExecuteTasksFileSystemCallbackDispatcher); }; @@ -851,7 +840,7 @@ ExtensionTaskExecutor::ExtensionTaskExecutor( ExtensionTaskExecutor::~ExtensionTaskExecutor() {} bool ExtensionTaskExecutor::ExecuteAndNotify( - const std::vector<GURL>& file_urls, + const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) { if (!FileBrowserHasAccessPermissionForFiles(file_urls)) return false; @@ -895,7 +884,7 @@ void ExtensionTaskExecutor::RequestFileEntryOnFileThread( const GURL& handler_base_url, const scoped_refptr<const Extension>& handler, int handler_pid, - const std::vector<GURL>& file_urls) { + const std::vector<FileSystemURL>& file_urls) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); GURL origin_url = handler_base_url.GetOrigin(); file_system_context_handler->OpenFileSystem( @@ -1036,15 +1025,14 @@ WebIntentTaskExecutor::WebIntentTaskExecutor( WebIntentTaskExecutor::~WebIntentTaskExecutor() {} bool WebIntentTaskExecutor::ExecuteAndNotify( - const std::vector<GURL>& file_urls, + const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) { if (!FileBrowserHasAccessPermissionForFiles(file_urls)) return false; for (size_t i = 0; i != file_urls.size(); ++i) { - fileapi::FileSystemURL url(file_urls[i]); extensions::LaunchPlatformAppWithPath(profile(), GetExtension(), - url.path()); + file_urls[i].path()); } if (!done.is_null()) @@ -1066,20 +1054,18 @@ AppTaskExecutor::AppTaskExecutor( AppTaskExecutor::~AppTaskExecutor() {} bool AppTaskExecutor::ExecuteAndNotify( - const std::vector<GURL>& file_urls, + const std::vector<FileSystemURL>& file_urls, const FileTaskFinishedCallback& done) { if (!FileBrowserHasAccessPermissionForFiles(file_urls)) return false; for (size_t i = 0; i != file_urls.size(); ++i) { - fileapi::FileSystemURL url(file_urls[i]); extensions::LaunchPlatformAppWithFileHandler(profile(), GetExtension(), - action_id_, url.path()); + action_id_, file_urls[i].path()); } if (!done.is_null()) done.Run(true); - return true; } diff --git a/chrome/browser/chromeos/extensions/file_handler_util.h b/chrome/browser/chromeos/extensions/file_handler_util.h index 3c939f8..f14a715 100644 --- a/chrome/browser/chromeos/extensions/file_handler_util.h +++ b/chrome/browser/chromeos/extensions/file_handler_util.h @@ -22,6 +22,10 @@ namespace extensions { class Extension; } // namespace extensions +namespace fileapi { +class FileSystemURL; +} + namespace file_handler_util { // Specifies the task type for a task id that represents some file action, Drive @@ -70,7 +74,7 @@ bool CrackTaskID(const std::string& task_id, // This generates a list of default tasks (tasks set as default by the user in // prefs) from the |common_tasks|. void FindDefaultTasks(Profile* profile, - const std::vector<GURL>& files_list, + const std::vector<FilePath>& files_list, const std::set<const FileBrowserHandler*>& common_tasks, std::set<const FileBrowserHandler*>* default_tasks); @@ -79,13 +83,14 @@ bool FindCommonTasks(Profile* profile, const std::vector<GURL>& files_list, std::set<const FileBrowserHandler*>* common_tasks); -// Finds a task for a file whose URL is |url|. +// Finds a task for a file whose URL is |url| and whose path is |path|. // Returns default task if one is defined (The default task is the task that is // assigned to file browser task button by default). If default task is not // found, tries to match the url with one of the builtin tasks. -bool GetTaskForURL(Profile* profile, - const GURL& url, - const FileBrowserHandler** handler); +bool GetTaskForURLAndPath(Profile* profile, + const GURL& url, + const FilePath& path, + const FileBrowserHandler** handler); // Used for returning success or failure from task executions. typedef base::Callback<void(bool)> FileTaskFinishedCallback; @@ -103,7 +108,7 @@ class FileTaskExecutor : public base::RefCountedThreadSafe<FileTaskExecutor> { const std::string& action_id); // Same as ExecuteAndNotify, but no notification is performed. - virtual bool Execute(const std::vector<GURL>& file_urls); + virtual bool Execute(const std::vector<fileapi::FileSystemURL>& file_urls); // Initiates execution of file handler task for each element of |file_urls|. // Return |false| if the execution cannot be initiated. Otherwise returns @@ -111,8 +116,9 @@ class FileTaskExecutor : public base::RefCountedThreadSafe<FileTaskExecutor> { // been handled. If there is an error during processing the list of files, the // caller will be informed of the failure via |done|, and the rest of // the files will not be processed. - virtual bool ExecuteAndNotify(const std::vector<GURL>& file_urls, - const FileTaskFinishedCallback& done) = 0; + virtual bool ExecuteAndNotify( + const std::vector<fileapi::FileSystemURL>& file_urls, + const FileTaskFinishedCallback& done) = 0; protected: explicit FileTaskExecutor(Profile* profile, @@ -123,7 +129,8 @@ class FileTaskExecutor : public base::RefCountedThreadSafe<FileTaskExecutor> { // Checks if the file browser extension had file access permissions for the // list of files. - bool FileBrowserHasAccessPermissionForFiles(const std::vector<GURL>& files); + bool FileBrowserHasAccessPermissionForFiles( + const std::vector<fileapi::FileSystemURL>& files); // Returns the profile that this task was created with. Profile* profile() { return profile_; } diff --git a/chrome/browser/chromeos/extensions/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager_util.cc index 0b63c919cb..f0c3d35 100644 --- a/chrome/browser/chromeos/extensions/file_manager_util.cc +++ b/chrome/browser/chromeos/extensions/file_manager_util.cc @@ -68,6 +68,7 @@ using content::PluginService; using content::UserMetricsAction; using extensions::Extension; using file_handler_util::FileTaskExecutor; +using fileapi::FileSystemURL; #define FILEBROWSER_EXTENSON_ID "hhaomjibdihmijegdhdafkllkbggdgoj" const char kFileBrowserDomain[] = FILEBROWSER_EXTENSON_ID; @@ -349,15 +350,17 @@ void ExecuteHandler(Profile* profile, // site for which file access permissions should be granted. GURL site = extensions::ExtensionSystem::Get(profile)->extension_service()-> GetSiteForExtensionId(kFileBrowserDomain); - fileapi::ExternalFileSystemMountPointProvider* external_provider = + fileapi::FileSystemContext* file_system_context = BrowserContext::GetStoragePartitionForSite(profile, site)-> - GetFileSystemContext()->external_provider(); - if (!external_provider) + GetFileSystemContext(); + + if (!file_system_context->external_provider()) return; - external_provider->GrantFullAccessToExtension(source_url.host()); + file_system_context->external_provider()->GrantFullAccessToExtension( + source_url.host()); - std::vector<GURL> urls; - urls.push_back(url); + std::vector<FileSystemURL> urls; + urls.push_back(file_system_context->CrackURL(url)); scoped_refptr<FileTaskExecutor> executor = FileTaskExecutor::Create(profile, source_url, kFileBrowserDomain, 0 /* no tab id */, extension_id, file_handler_util::kTaskFile, action_id); @@ -439,7 +442,7 @@ bool ExecuteDefaultHandler(Profile* profile, const FilePath& path) { return false; const FileBrowserHandler* handler; - if (!file_handler_util::GetTaskForURL(profile, url, &handler)) + if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) return false; std::string extension_id = handler->extension_id(); @@ -547,7 +550,7 @@ void CheckIfDirectoryExistsOnIOThread( const fileapi::FileSystemOperation::StatusCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - fileapi::FileSystemURL file_system_url(url); + fileapi::FileSystemURL file_system_url = file_system_context->CrackURL(url); base::PlatformFileError error = base::PLATFORM_FILE_OK; fileapi::FileSystemOperation* operation = file_system_context->CreateFileSystemOperation(file_system_url, &error); diff --git a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc index 2c818f2..eb46e02 100644 --- a/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc +++ b/chrome/browser/extensions/api/downloads/downloads_api_unittest.cc @@ -726,13 +726,12 @@ class HTML5FileWriter { } fileapi::FileSystemOperation* operation() { - return fs_->CreateFileSystemOperation( - fileapi::FileSystemURL(GURL(root_)), NULL); + return fs_->CreateFileSystemOperation(fs_->CrackURL(GURL(root_)), NULL); } void CreateFile() { CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - operation()->CreateFile(fileapi::FileSystemURL(GURL(root_ + filename_)), + operation()->CreateFile(fs_->CrackURL(GURL(root_ + filename_)), kExclusive, base::Bind( &HTML5FileWriter::CreateFileCallback, base::Unretained(this))); } @@ -746,7 +745,7 @@ class HTML5FileWriter { blob_url(), blob_data_); operation()->Write( url_request_context_.get(), - fileapi::FileSystemURL(GURL(root_ + filename_)), + fs_->CrackURL(GURL(root_ + filename_)), blob_url(), 0, // offset base::Bind(&HTML5FileWriter::WriteCallback, base::Unretained(this))); diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc index f652f1f..5cbeeb2 100644 --- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc +++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_api.cc @@ -86,15 +86,17 @@ bool IsValidServiceName(const std::string& service_name, std::string* error) { bool SyncFileSystemDeleteFileSystemFunction::RunImpl() { std::string url; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); - fileapi::FileSystemURL file_system_url((GURL(url))); - if (!IsValidServiceName(file_system_url.filesystem_id(), &error_)) { - return false; - } scoped_refptr<fileapi::FileSystemContext> file_system_context = BrowserContext::GetStoragePartition( profile(), render_view_host()->GetSiteInstance())->GetFileSystemContext(); + fileapi::FileSystemURL file_system_url( + file_system_context->CrackURL(GURL(url))); + + if (!IsValidServiceName(file_system_url.filesystem_id(), &error_)) + return false; + BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, @@ -209,10 +211,16 @@ void SyncFileSystemRequestFileSystemFunction::DidOpenFileSystem( bool SyncFileSystemGetUsageAndQuotaFunction::RunImpl() { std::string url; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); - fileapi::FileSystemURL file_system_url((GURL(url))); - if (!IsValidServiceName(file_system_url.filesystem_id(), &error_)) { + + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition( + profile(), + render_view_host()->GetSiteInstance())->GetFileSystemContext(); + fileapi::FileSystemURL file_system_url( + file_system_context->CrackURL(GURL(url))); + + if (!IsValidServiceName(file_system_url.filesystem_id(), &error_)) return false; - } scoped_refptr<quota::QuotaManager> quota_manager = BrowserContext::GetStoragePartition( @@ -235,7 +243,13 @@ bool SyncFileSystemGetUsageAndQuotaFunction::RunImpl() { bool SyncFileSystemGetFileSyncStatusFunction::RunImpl() { std::string url; EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &url)); - fileapi::FileSystemURL file_system_url((GURL(url))); + + scoped_refptr<fileapi::FileSystemContext> file_system_context = + BrowserContext::GetStoragePartition( + profile(), + render_view_host()->GetSiteInstance())->GetFileSystemContext(); + fileapi::FileSystemURL file_system_url( + file_system_context->CrackURL(GURL(url))); SyncFileSystemServiceFactory::GetForProfile(profile())->GetFileSyncStatus( file_system_url, diff --git a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc index 4cefacc..976f165 100644 --- a/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc +++ b/chrome/browser/extensions/api/sync_file_system/sync_file_system_apitest.cc @@ -75,9 +75,10 @@ ACTION_P2(UpdateRemoteChangeQueue, origin, mock_remote_service) { } ACTION_P2(ReturnWithFakeFileAddedStatus, origin, mock_remote_service) { - fileapi::FileSystemURL mock_url(*origin, - fileapi::kFileSystemTypeTest, - FilePath(FILE_PATH_LITERAL("foo"))); + fileapi::FileSystemURL mock_url = + fileapi::FileSystemURL::CreateForTest(*origin, + fileapi::kFileSystemTypeTest, + FilePath(FILE_PATH_LITERAL("foo"))); mock_remote_service->NotifyRemoteChangeQueueUpdated(0); base::MessageLoopProxy::current()->PostTask( FROM_HERE, base::Bind(arg1, diff --git a/content/browser/fileapi/fileapi_message_filter.cc b/content/browser/fileapi/fileapi_message_filter.cc index dcba381..0c01f38 100644 --- a/content/browser/fileapi/fileapi_message_filter.cc +++ b/content/browser/fileapi/fileapi_message_filter.cc @@ -115,7 +115,7 @@ void FileAPIMessageFilter::OnChannelClosing() { for (std::multiset<GURL>::const_iterator iter = open_filesystem_urls_.begin(); iter != open_filesystem_urls_.end(); ++iter) { - FileSystemURL url(*iter); + FileSystemURL url(context_->CrackURL(*iter)); FileSystemOperation* operation = context_->CreateFileSystemOperation( url, NULL); if (operation) @@ -207,8 +207,8 @@ void FileAPIMessageFilter::OnMove( int request_id, const GURL& src_path, const GURL& dest_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL src_url(src_path); - FileSystemURL dest_url(dest_path); + FileSystemURL src_url(context_->CrackURL(src_path)); + FileSystemURL dest_url(context_->CrackURL(dest_path)); const int src_permissions = fileapi::kReadFilePermissions | fileapi::kWriteFilePermissions; if (!HasPermissionsForFile(src_url, src_permissions, &error) || @@ -230,8 +230,8 @@ void FileAPIMessageFilter::OnCopy( int request_id, const GURL& src_path, const GURL& dest_path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL src_url(src_path); - FileSystemURL dest_url(dest_path); + FileSystemURL src_url(context_->CrackURL(src_path)); + FileSystemURL dest_url(context_->CrackURL(dest_path)); if (!HasPermissionsForFile(src_url, fileapi::kReadFilePermissions, &error) || !HasPermissionsForFile( dest_url, fileapi::kCreateFilePermissions, &error)) { @@ -251,7 +251,7 @@ void FileAPIMessageFilter::OnRemove( int request_id, const GURL& path, bool recursive) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -269,7 +269,7 @@ void FileAPIMessageFilter::OnReadMetadata( int request_id, const GURL& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -288,7 +288,7 @@ void FileAPIMessageFilter::OnCreate( bool is_directory, bool recursive) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kCreateFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -312,7 +312,7 @@ void FileAPIMessageFilter::OnExists( int request_id, const GURL& path, bool is_directory) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -336,7 +336,7 @@ void FileAPIMessageFilter::OnReadDirectory( int request_id, const GURL& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kReadFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -362,7 +362,7 @@ void FileAPIMessageFilter::OnWrite( return; } - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); base::PlatformFileError error; if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); @@ -382,7 +382,7 @@ void FileAPIMessageFilter::OnTruncate( const GURL& path, int64 length) { base::PlatformFileError error; - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, fileapi::kWriteFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -402,7 +402,7 @@ void FileAPIMessageFilter::OnTouchFile( const base::Time& last_access_time, const base::Time& last_modified_time) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); base::PlatformFileError error; if (!HasPermissionsForFile(url, fileapi::kCreateFilePermissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); @@ -440,7 +440,7 @@ void FileAPIMessageFilter::OnOpenFile( base::PlatformFileError error; const int open_permissions = base::PLATFORM_FILE_OPEN | (file_flags & fileapi::kOpenFilePermissions); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!HasPermissionsForFile(url, open_permissions, &error)) { Send(new FileSystemMsg_DidFail(request_id, error)); return; @@ -463,7 +463,7 @@ void FileAPIMessageFilter::OnNotifyCloseFile(const GURL& path) { DCHECK(iter != open_filesystem_urls_.end()); open_filesystem_urls_.erase(iter); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); // Do not use GetNewOperation() here, because NotifyCloseFile is a one-way // operation that does not have request_id by which we respond back. @@ -475,7 +475,7 @@ void FileAPIMessageFilter::OnNotifyCloseFile(const GURL& path) { void FileAPIMessageFilter::OnWillUpdate(const GURL& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!url.is_valid()) return; const UpdateObserverList* observers = @@ -487,7 +487,7 @@ void FileAPIMessageFilter::OnWillUpdate(const GURL& path) { void FileAPIMessageFilter::OnDidUpdate(const GURL& path, int64 delta) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!url.is_valid()) return; const UpdateObserverList* observers = @@ -503,7 +503,7 @@ void FileAPIMessageFilter::OnSyncGetPlatformPath( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); DCHECK(platform_path); *platform_path = FilePath(); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); if (!url.is_valid()) return; @@ -541,7 +541,7 @@ void FileAPIMessageFilter::OnSyncGetPlatformPath( void FileAPIMessageFilter::OnCreateSnapshotFile( int request_id, const GURL& blob_url, const GURL& path) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - FileSystemURL url(path); + FileSystemURL url(context_->CrackURL(path)); base::Callback<void(const FilePath&)> register_file_callback = base::Bind(&FileAPIMessageFilter::RegisterFileAsBlob, this, blob_url, url); diff --git a/content/content_tests.gypi b/content/content_tests.gypi index 9b286a3..c77d4f5 100644 --- a/content/content_tests.gypi +++ b/content/content_tests.gypi @@ -417,6 +417,7 @@ '../webkit/dom_storage/dom_storage_map_unittest.cc', '../webkit/dom_storage/session_storage_database_unittest.cc', '../webkit/fileapi/external_mount_points_unittest.cc', + '../webkit/fileapi/file_system_context_unittest.cc', '../webkit/fileapi/file_system_database_test_helper.cc', '../webkit/fileapi/file_system_database_test_helper.h', '../webkit/fileapi/file_system_directory_database_unittest.cc', diff --git a/webkit/blob/blob_url_request_job.cc b/webkit/blob/blob_url_request_job.cc index 279c1ee..68befac 100644 --- a/webkit/blob/blob_url_request_job.cc +++ b/webkit/blob/blob_url_request_job.cc @@ -562,7 +562,7 @@ void BlobURLRequestJob::CreateFileStreamReader(size_t index, break; case BlobData::Item::TYPE_FILE_FILESYSTEM: reader = file_system_context_->CreateFileStreamReader( - fileapi::FileSystemURL(item.url()), + fileapi::FileSystemURL(file_system_context_->CrackURL(item.url())), item.offset() + additional_offset, item.expected_modification_time()); break; diff --git a/webkit/blob/blob_url_request_job_unittest.cc b/webkit/blob/blob_url_request_job_unittest.cc index 54d8f3a..1ed897b 100644 --- a/webkit/blob/blob_url_request_job_unittest.cc +++ b/webkit/blob/blob_url_request_job_unittest.cc @@ -203,9 +203,11 @@ class BlobURLRequestJobTest : public testing::Test { void WriteFileSystemFile(const std::string& filename, const char* buf, int buf_size, base::Time* modification_time) { - fileapi::FileSystemURL url(GURL(kFileSystemURLOrigin), - kFileSystemType, - FilePath().AppendASCII(filename)); + fileapi::FileSystemURL url = + file_system_context_->CreateCrackedFileSystemURL( + GURL(kFileSystemURLOrigin), + kFileSystemType, + FilePath().AppendASCII(filename)); fileapi::FileSystemFileUtil* file_util = file_system_context_->GetFileUtil(kFileSystemType); diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider.cc b/webkit/chromeos/fileapi/cros_mount_point_provider.cc index 33bcbf1..9a8aafb 100644 --- a/webkit/chromeos/fileapi/cros_mount_point_provider.cc +++ b/webkit/chromeos/fileapi/cros_mount_point_provider.cc @@ -89,18 +89,21 @@ FilePath CrosMountPointProvider::GetFileSystemRootPathOnFileThread( bool CrosMountPointProvider::IsAccessAllowed( const fileapi::FileSystemURL& url) { - if (!CanHandleURL(url)) + if (!url.is_valid()) return false; - // No extra check is needed for isolated file systems. - if (url.mount_type() == fileapi::kFileSystemTypeIsolated) - return true; - // Permit access to mount points from internal WebUI. const GURL& origin_url = url.origin(); if (origin_url.SchemeIs(kChromeUIScheme)) return true; + // No extra check is needed for isolated file systems. + if (url.mount_type() == fileapi::kFileSystemTypeIsolated) + return true; + + if (!CanHandleURL(url)) + return false; + std::string extension_id = origin_url.host(); // Check first to make sure this extension has fileBrowserHander permissions. if (!special_storage_policy_->IsFileHandler(extension_id)) diff --git a/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc index 3dfda44..b586584 100644 --- a/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc +++ b/webkit/chromeos/fileapi/cros_mount_point_provider_unittest.cc @@ -16,13 +16,18 @@ #define FPL(x) FILE_PATH_LITERAL(x) +using fileapi::ExternalMountPoints; +using fileapi::FileSystemURL; + namespace { -fileapi::FileSystemURL CreateFileSystemURL(const std::string& extension, - const char* path) { - return fileapi::FileSystemURL(GURL("chrome-extension://" + extension + "/"), - fileapi::kFileSystemTypeNativeLocal, - FilePath::FromUTF8Unsafe(path)); +FileSystemURL CreateFileSystemURL(const std::string& extension, + const char* path, + ExternalMountPoints* mount_points) { + return mount_points->CreateCrackedFileSystemURL( + GURL("chrome-extension://" + extension + "/"), + fileapi::kFileSystemTypeExternal, + FilePath::FromUTF8Unsafe(path)); } TEST(CrosMountPointProviderTest, DefaultMountPoints) { @@ -200,56 +205,58 @@ TEST(CrosMountPointProviderTest, AccessPermissions) { // Provider specific mount point access. EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "removable/foo"))); + CreateFileSystemURL(extension, "removable/foo", mount_points.get()))); provider.GrantFileAccessToExtension(extension, FilePath(FPL("removable/foo"))); EXPECT_TRUE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "removable/foo"))); + CreateFileSystemURL(extension, "removable/foo", mount_points.get()))); EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "removable/foo1"))); + CreateFileSystemURL(extension, "removable/foo1", mount_points.get()))); // System mount point access. EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "system/foo"))); + CreateFileSystemURL(extension, "system/foo", system_mount_points.get()))); provider.GrantFileAccessToExtension(extension, FilePath(FPL("system/foo"))); EXPECT_TRUE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "system/foo"))); - EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "system/foo1"))); + CreateFileSystemURL(extension, "system/foo", system_mount_points.get()))); + EXPECT_FALSE(provider.IsAccessAllowed(CreateFileSystemURL( + extension, "system/foo1", system_mount_points.get()))); // oem is restricted file system. provider.GrantFileAccessToExtension(extension, FilePath(FPL("oem/foo"))); // The extension should not be able to access the file even if // GrantFileAccessToExtension was called. EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "oem/foo"))); + CreateFileSystemURL(extension, "oem/foo", mount_points.get()))); provider.GrantFullAccessToExtension(extension); // The extension should be able to access restricted file system after it was // granted full access. EXPECT_TRUE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "oem/foo"))); + CreateFileSystemURL(extension, "oem/foo", mount_points.get()))); // The extension which was granted full access should be able to access any - // path on current file systems. - EXPECT_TRUE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "removable/foo1"))); + // path on curent file systems. EXPECT_TRUE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "system/foo1"))); + CreateFileSystemURL(extension, "removable/foo1", mount_points.get()))); + EXPECT_TRUE(provider.IsAccessAllowed(CreateFileSystemURL( + extension, "system/foo1", system_mount_points.get()))); - // The extension still cannot access new mount points. + // The extension cannot access new mount points. + // TODO(tbarzic): This should probably be changed. ASSERT_TRUE(provider.AddLocalMountPoint(FilePath(FPL("/foo/test")))); EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "test_/foo"))); + CreateFileSystemURL(extension, "test_/foo", mount_points.get()))); provider.RevokeAccessForExtension(extension); EXPECT_FALSE(provider.IsAccessAllowed( - CreateFileSystemURL(extension, "removable/foo"))); + CreateFileSystemURL(extension, "removable/foo", mount_points.get()))); - fileapi::FileSystemURL internal_url(GURL("chrome://foo"), - fileapi::kFileSystemTypeExternal, - FilePath(FPL("removable/"))); + fileapi::FileSystemURL internal_url = FileSystemURL::CreateForTest( + GURL("chrome://foo"), + fileapi::kFileSystemTypeExternal, + FilePath(FPL("removable/"))); // Internal WebUI should have full access. EXPECT_TRUE(provider.IsAccessAllowed(internal_url)); } diff --git a/webkit/fileapi/external_mount_points.cc b/webkit/fileapi/external_mount_points.cc index 9abba42..126c931 100644 --- a/webkit/fileapi/external_mount_points.cc +++ b/webkit/fileapi/external_mount_points.cc @@ -8,6 +8,7 @@ #include "base/lazy_instance.h" #include "base/path_service.h" #include "base/stl_util.h" +#include "webkit/fileapi/file_system_url.h" #include "webkit/fileapi/remote_file_system_proxy.h" namespace { @@ -154,6 +155,11 @@ bool ExternalMountPoints::RegisterRemoteFileSystem( return true; } +bool ExternalMountPoints::HandlesFileSystemMountType( + FileSystemType type) const { + return type == kFileSystemTypeExternal; +} + bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) { base::AutoLock locker(lock_); NameToInstance::iterator found = instance_map_.find(mount_name); @@ -221,6 +227,32 @@ bool ExternalMountPoints::CrackVirtualPath(const FilePath& virtual_path, return true; } +FileSystemURL ExternalMountPoints::CrackURL(const GURL& url) const { + FileSystemURL filesystem_url = FileSystemURL(url); + if (!filesystem_url.is_valid()) + return FileSystemURL(); + return CreateCrackedFileSystemURL(filesystem_url.origin(), + filesystem_url.mount_type(), + filesystem_url.path()); +} + +FileSystemURL ExternalMountPoints::CreateCrackedFileSystemURL( + const GURL& origin, + FileSystemType type, + const FilePath& path) const { + if (!HandlesFileSystemMountType(type)) + return FileSystemURL(); + + std::string mount_name; + FileSystemType cracked_type; + FilePath cracked_path; + if (!CrackVirtualPath(path, &mount_name, &cracked_type, &cracked_path)) + return FileSystemURL(); + + return FileSystemURL(origin, type, path, + mount_name, cracked_type, cracked_path); +} + RemoteFileSystemProxyInterface* ExternalMountPoints::GetRemoteFileSystemProxy( const std::string& mount_name) const { base::AutoLock locker(lock_); diff --git a/webkit/fileapi/external_mount_points.h b/webkit/fileapi/external_mount_points.h index fe8d4d0..f2d8e29 100644 --- a/webkit/fileapi/external_mount_points.h +++ b/webkit/fileapi/external_mount_points.h @@ -18,6 +18,7 @@ class FilePath; namespace fileapi { +class FileSystemURL; class RemoteFileSystemProxyInterface; } @@ -69,6 +70,7 @@ class WEBKIT_STORAGE_EXPORT ExternalMountPoints const FilePath& path); // MountPoints overrides. + virtual bool HandlesFileSystemMountType(FileSystemType type) const OVERRIDE; virtual bool RevokeFileSystem(const std::string& mount_name) OVERRIDE; virtual bool GetRegisteredPath(const std::string& mount_name, FilePath* path) const OVERRIDE; @@ -76,6 +78,11 @@ class WEBKIT_STORAGE_EXPORT ExternalMountPoints std::string* mount_name, FileSystemType* type, FilePath* path) const OVERRIDE; + virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE; + virtual FileSystemURL CreateCrackedFileSystemURL( + const GURL& origin, + FileSystemType type, + const FilePath& path) const OVERRIDE; // Retrieves the remote file system proxy for the registered file system. // Returns NULL if there is no file system with the given name, or if the file diff --git a/webkit/fileapi/external_mount_points_unittest.cc b/webkit/fileapi/external_mount_points_unittest.cc index 379d146..4668264 100644 --- a/webkit/fileapi/external_mount_points_unittest.cc +++ b/webkit/fileapi/external_mount_points_unittest.cc @@ -8,6 +8,7 @@ #include "base/file_path.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/file_system_url.h" #define FPL FILE_PATH_LITERAL @@ -17,6 +18,8 @@ #define DRIVE #endif +using fileapi::FileSystemURL; + namespace { TEST(ExternalMountPointsTest, AddMountPoint) { @@ -223,5 +226,237 @@ TEST(ExternalMountPointsTest, GetVirtualPath) { } } +TEST(ExternalMountPointsTest, HandlesFileSystemMountType) { + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + const GURL test_origin("http://chromium.org"); + const FilePath test_path(FPL("/mount")); + + // Should handle External File System. + EXPECT_TRUE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeExternal)); + + // Shouldn't handle the rest. + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeIsolated)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeTemporary)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeTest)); + // Not even if it's external subtype. + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeNativeLocal)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeRestrictedNativeLocal)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeDrive)); + EXPECT_FALSE(mount_points->HandlesFileSystemMountType( + fileapi::kFileSystemTypeSyncable)); +} + +TEST(ExternalMountPointsTest, CreateCrackedFileSystemURL) { + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + const GURL kTestOrigin("http://chromium.org"); + + mount_points->RegisterFileSystem("c", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/a/b/c"))); + mount_points->RegisterFileSystem("c(1)", + fileapi::kFileSystemTypeDrive, + FilePath(DRIVE FPL("/a/b/c(1)"))); + mount_points->RegisterFileSystem("empty_path", + fileapi::kFileSystemTypeSyncable, + FilePath(FPL(""))); + mount_points->RegisterFileSystem("mount", + fileapi::kFileSystemTypeDrive, + FilePath(DRIVE FPL("/root"))); + + // Try cracking invalid GURL. + FileSystemURL invalid = mount_points->CrackURL(GURL("http://chromium.og")); + EXPECT_FALSE(invalid.is_valid()); + + // Try cracking isolated path. + FileSystemURL isolated = mount_points->CreateCrackedFileSystemURL( + kTestOrigin, fileapi::kFileSystemTypeIsolated, FilePath(FPL("c"))); + EXPECT_FALSE(isolated.is_valid()); + + // Try native local which is not cracked. + FileSystemURL native_local = mount_points->CreateCrackedFileSystemURL( + kTestOrigin, fileapi::kFileSystemTypeNativeLocal, FilePath(FPL("c"))); + EXPECT_FALSE(native_local.is_valid()); + + struct TestCase { + const FilePath::CharType* const path; + bool expect_valid; + fileapi::FileSystemType expect_type; + const FilePath::CharType* const expect_path; + const char* const expect_fs_id; + }; + + const TestCase kTestCases[] = { + { FPL("c/d/e"), + true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" }, + { FPL("c(1)/d/e"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)/d/e"), "c(1)" }, + { FPL("c(1)"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"), "c(1)" }, + { FPL("empty_path/a"), + true, fileapi::kFileSystemTypeSyncable, FPL("a"), "empty_path" }, + { FPL("empty_path"), + true, fileapi::kFileSystemTypeSyncable, FPL(""), "empty_path" }, + { FPL("mount/a/b"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" }, + { FPL("mount"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root"), "mount" }, + { FPL("cc"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL(""), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL(".."), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + // Absolte paths. + { FPL("/c/d/e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/c(1)/d/e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/empty_path"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + // PAth references parent. + { FPL("c/d/../e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/empty_path/a/../b"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + { FPL("c/d\\e"), + true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" }, + { FPL("mount\\a\\b"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" }, +#endif + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + FileSystemURL cracked = mount_points->CreateCrackedFileSystemURL( + kTestOrigin, + fileapi::kFileSystemTypeExternal, + FilePath(kTestCases[i].path)); + + EXPECT_EQ(kTestCases[i].expect_valid, cracked.is_valid()) + << "Test case index: " << i; + + if (!kTestCases[i].expect_valid) + continue; + + EXPECT_EQ(kTestOrigin, cracked.origin()) + << "Test case index: " << i; + EXPECT_EQ(kTestCases[i].expect_type, cracked.type()) + << "Test case index: " << i; + EXPECT_EQ(FilePath(kTestCases[i].expect_path).NormalizePathSeparators(), + cracked.path()) + << "Test case index: " << i; + EXPECT_EQ(FilePath(kTestCases[i].path).NormalizePathSeparators(), + cracked.virtual_path()) + << "Test case index: " << i; + EXPECT_EQ(kTestCases[i].expect_fs_id, cracked.filesystem_id()) + << "Test case index: " << i; + EXPECT_EQ(fileapi::kFileSystemTypeExternal, cracked.mount_type()) + << "Test case index: " << i; + } +} + +TEST(ExternalMountPointsTest, CrackVirtualPath) { + scoped_refptr<fileapi::ExternalMountPoints> mount_points( + fileapi::ExternalMountPoints::CreateRefCounted()); + + const GURL kTestOrigin("http://chromium.org"); + + mount_points->RegisterFileSystem("c", + fileapi::kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/a/b/c"))); + mount_points->RegisterFileSystem("c(1)", + fileapi::kFileSystemTypeDrive, + FilePath(DRIVE FPL("/a/b/c(1)"))); + mount_points->RegisterFileSystem("empty_path", + fileapi::kFileSystemTypeSyncable, + FilePath(FPL(""))); + mount_points->RegisterFileSystem("mount", + fileapi::kFileSystemTypeDrive, + FilePath(DRIVE FPL("/root"))); + + struct TestCase { + const FilePath::CharType* const path; + bool expect_valid; + fileapi::FileSystemType expect_type; + const FilePath::CharType* const expect_path; + const char* const expect_name; + }; + + const TestCase kTestCases[] = { + { FPL("c/d/e"), + true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" }, + { FPL("c(1)/d/e"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)/d/e"), "c(1)" }, + { FPL("c(1)"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/a/b/c(1)"), "c(1)" }, + { FPL("empty_path/a"), + true, fileapi::kFileSystemTypeSyncable, FPL("a"), "empty_path" }, + { FPL("empty_path"), + true, fileapi::kFileSystemTypeSyncable, FPL(""), "empty_path" }, + { FPL("mount/a/b"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" }, + { FPL("mount"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root"), "mount" }, + { FPL("cc"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL(""), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL(".."), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + // Absolte paths. + { FPL("/c/d/e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/c(1)/d/e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/empty_path"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + // PAth references parent. + { FPL("c/d/../e"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, + { FPL("/empty_path/a/../b"), + false, fileapi::kFileSystemTypeUnknown, FPL(""), "" }, +#if defined(FILE_PATH_USES_WIN_SEPARATORS) + { FPL("c/d\\e"), + true, fileapi::kFileSystemTypeNativeLocal, DRIVE FPL("/a/b/c/d/e"), "c" }, + { FPL("mount\\a\\b"), + true, fileapi::kFileSystemTypeDrive, DRIVE FPL("/root/a/b"), "mount" }, +#endif + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + std::string cracked_name; + fileapi::FileSystemType cracked_type; + FilePath cracked_path; + EXPECT_EQ(kTestCases[i].expect_valid, + mount_points->CrackVirtualPath(FilePath(kTestCases[i].path), + &cracked_name, &cracked_type, &cracked_path)) + << "Test case index: " << i; + + if (!kTestCases[i].expect_valid) + continue; + + EXPECT_EQ(kTestCases[i].expect_type, cracked_type) + << "Test case index: " << i; + EXPECT_EQ(FilePath(kTestCases[i].expect_path).NormalizePathSeparators(), + cracked_path) + << "Test case index: " << i; + EXPECT_EQ(kTestCases[i].expect_name, cracked_name) + << "Test case index: " << i; + } +} + } // namespace diff --git a/webkit/fileapi/file_system_context.cc b/webkit/fileapi/file_system_context.cc index bf285ea..8d3ac54 100644 --- a/webkit/fileapi/file_system_context.cc +++ b/webkit/fileapi/file_system_context.cc @@ -18,6 +18,7 @@ #include "webkit/fileapi/file_system_util.h" #include "webkit/fileapi/isolated_context.h" #include "webkit/fileapi/isolated_mount_point_provider.h" +#include "webkit/fileapi/mount_points.h" #include "webkit/fileapi/sandbox_mount_point_provider.h" #include "webkit/fileapi/syncable/local_file_change_tracker.h" #include "webkit/fileapi/syncable/local_file_sync_context.h" @@ -75,13 +76,21 @@ FileSystemContext::FileSystemContext( this, options.is_incognito())); } #if defined(OS_CHROMEOS) + // TODO(tbarzic): Pass this through ctor. + scoped_refptr<ExternalMountPoints> external_mount_points = + ExternalMountPoints::CreateRefCounted(); + // |external_provider_| will take a reference or external_mount_points so this + // doesn't have to retain one for itself. external_provider_.reset( new chromeos::CrosMountPointProvider( special_storage_policy, - // TODO(tbarzic): Switch this to |external_mount_points_|. - fileapi::ExternalMountPoints::GetSystemInstance(), - fileapi::ExternalMountPoints::GetSystemInstance())); + external_mount_points, + ExternalMountPoints::GetSystemInstance())); + url_crackers_.push_back(external_mount_points.get()); #endif + + url_crackers_.push_back(ExternalMountPoints::GetSystemInstance()); + url_crackers_.push_back(IsolatedContext::GetInstance()); } bool FileSystemContext::DeleteDataForOriginOnFileThread( @@ -306,6 +315,17 @@ void FileSystemContext::set_sync_context( sync_context_ = sync_context; } +FileSystemURL FileSystemContext::CrackURL(const GURL& url) const { + return CrackFileSystemURL(FileSystemURL(url)); +} + +FileSystemURL FileSystemContext::CreateCrackedFileSystemURL( + const GURL& origin, + FileSystemType type, + const FilePath& path) const { + return CrackFileSystemURL(FileSystemURL(origin, type, path)); +} + FileSystemContext::~FileSystemContext() { task_runners_->file_task_runner()->DeleteSoon( FROM_HERE, change_tracker_.release()); @@ -321,4 +341,27 @@ void FileSystemContext::DeleteOnCorrectThread() const { delete this; } +FileSystemURL FileSystemContext::CrackFileSystemURL( + const FileSystemURL& url) const { + if (!url.is_valid()) + return FileSystemURL(); + + // The returned value in case there is no crackers which can crack the url. + // This is valid situation for non isolated/external file systems. + FileSystemURL result = url; + + for (size_t i = 0; i < url_crackers_.size(); ++i) { + if (!url_crackers_[i]->HandlesFileSystemMountType(url.type())) + continue; + + result = url_crackers_[i]->CreateCrackedFileSystemURL(url.origin(), + url.type(), + url.path()); + if (result.is_valid()) + return result; + } + + return result; +} + } // namespace fileapi diff --git a/webkit/fileapi/file_system_context.h b/webkit/fileapi/file_system_context.h index e71fe73..4dd496f 100644 --- a/webkit/fileapi/file_system_context.h +++ b/webkit/fileapi/file_system_context.h @@ -7,6 +7,7 @@ #include <map> #include <string> +#include <vector> #include "base/callback.h" #include "base/memory/ref_counted.h" @@ -14,6 +15,7 @@ #include "base/platform_file.h" #include "base/sequenced_task_runner_helpers.h" #include "webkit/fileapi/file_system_types.h" +#include "webkit/fileapi/file_system_url.h" #include "webkit/fileapi/task_runner_bound_observer_list.h" #include "webkit/storage/webkit_storage_export.h" @@ -31,6 +33,7 @@ class FileStreamReader; namespace fileapi { class ExternalFileSystemMountPointProvider; +class ExternalMountPoints; class FileSystemFileUtil; class FileSystemMountPointProvider; class FileSystemOperation; @@ -40,8 +43,9 @@ class FileSystemTaskRunners; class FileSystemURL; class IsolatedMountPointProvider; class LocalFileChangeTracker; -class SandboxMountPointProvider; class LocalFileSyncContext; +class MountPoints; +class SandboxMountPointProvider; struct DefaultContextDeleter; @@ -138,9 +142,9 @@ class WEBKIT_STORAGE_EXPORT FileSystemContext FileSystemType type, const DeleteFileSystemCallback& callback); - // Creates a new FileSystemOperation instance by cracking - // the given filesystem URL |url| to get an appropriate MountPointProvider - // and calling the provider's corresponding CreateFileSystemOperation method. + // Creates a new FileSystemOperation instance by getting an appropriate + // MountPointProvider for |url| and calling the provider's corresponding + // CreateFileSystemOperation method. // The resolved MountPointProvider could perform further specialization // depending on the filesystem type pointed by the |url|. FileSystemOperation* CreateFileSystemOperation( @@ -177,6 +181,14 @@ class WEBKIT_STORAGE_EXPORT FileSystemContext const FilePath& partition_path() const { return partition_path_; } + // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from |url|. + FileSystemURL CrackURL(const GURL& url) const; + // Same as |CrackFileSystemURL|, but cracks FileSystemURL created from method + // arguments. + FileSystemURL CreateCrackedFileSystemURL(const GURL& origin, + FileSystemType type, + const FilePath& path) const; + private: friend struct DefaultContextDeleter; friend class base::DeleteHelper<FileSystemContext>; @@ -186,6 +198,15 @@ class WEBKIT_STORAGE_EXPORT FileSystemContext void DeleteOnCorrectThread() const; + // For non-cracked isolated and external mount points, returns a FileSystemURL + // created by cracking |url|. The url is cracked using MountPoints registered + // as |url_crackers_|. If the url cannot be cracked, returns invalid + // FileSystemURL. + // + // If the original url does not point to an isolated or external filesystem, + // returns the original url, without attempting to crack it. + FileSystemURL CrackFileSystemURL(const FileSystemURL& url) const; + scoped_ptr<FileSystemTaskRunners> task_runners_; scoped_refptr<quota::QuotaManagerProxy> quota_manager_proxy_; @@ -198,6 +219,10 @@ class WEBKIT_STORAGE_EXPORT FileSystemContext // Registered mount point providers. std::map<FileSystemType, FileSystemMountPointProvider*> provider_map_; + // MountPoints used to crack FileSystemURLs. The MountPoints are ordered + // in order they should try to crack a FileSystemURL. + std::vector<MountPoints*> url_crackers_; + // The base path of the storage partition for this context. const FilePath partition_path_; diff --git a/webkit/fileapi/file_system_context_unittest.cc b/webkit/fileapi/file_system_context_unittest.cc new file mode 100644 index 0000000..c1ee85c --- /dev/null +++ b/webkit/fileapi/file_system_context_unittest.cc @@ -0,0 +1,219 @@ +// Copyright (c) 2013 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_context.h" + +#include "base/files/scoped_temp_dir.h" +#include "base/message_loop.h" +#include "base/stringprintf.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/external_mount_points.h" +#include "webkit/fileapi/file_system_task_runners.h" +#include "webkit/fileapi/isolated_context.h" +#include "webkit/fileapi/mock_file_system_options.h" +#include "webkit/quota/mock_quota_manager.h" +#include "webkit/quota/mock_special_storage_policy.h" + +#define FPL(x) FILE_PATH_LITERAL(x) + +#if defined(FILE_PATH_USES_DRIVE_LETTERS) +#define DRIVE FPL("C:") +#else +#define DRIVE +#endif + +namespace fileapi { + +namespace { + +const char kTestOrigin[] = "http://chromium.org/"; +const FilePath::CharType kVirtualPathNoRoot[] = FPL("root/file"); + +GURL CreateRawFileSystemURL(const std::string& type_str, + const std::string& fs_id) { + std::string url_str = base::StringPrintf( + "filesystem:http://chromium.org/%s/%s/root/file", + type_str.c_str(), + fs_id.c_str()); + return GURL(url_str); +} + +class FileSystemContextTest : public testing::Test { + public: + FileSystemContextTest() {} + + void SetUp() { + ASSERT_TRUE(data_dir_.CreateUniqueTempDir()); + + scoped_refptr<quota::SpecialStoragePolicy> storage_policy( + new quota::MockSpecialStoragePolicy()); + + mock_quota_manager_ = new quota::MockQuotaManager( + false /* is_incognito */, + data_dir_.path(), + base::MessageLoopProxy::current(), + base::MessageLoopProxy::current(), + storage_policy); + + file_system_context_ = new FileSystemContext( + FileSystemTaskRunners::CreateMockTaskRunners(), + storage_policy, + mock_quota_manager_->proxy(), + data_dir_.path(), + CreateAllowFileAccessOptions()); + } + + protected: + FileSystemContext* file_system_context() { + return file_system_context_.get(); + } + + // Verifies a *valid* filesystem url has expected values. + void ExpectFileSystemURLMatches(const FileSystemURL& url, + const GURL& expect_origin, + FileSystemType expect_mount_type, + FileSystemType expect_type, + const FilePath& expect_path, + const FilePath& expect_virtual_path, + const std::string& expect_filesystem_id) { + ASSERT_TRUE(url.is_valid()); + + EXPECT_EQ(expect_origin, url.origin()); + EXPECT_EQ(expect_mount_type, url.mount_type()); + EXPECT_EQ(expect_type, url.type()); + EXPECT_EQ(expect_path, url.path()); + EXPECT_EQ(expect_virtual_path, url.virtual_path()); + EXPECT_EQ(expect_filesystem_id, url.filesystem_id()); + } + + private: + base::ScopedTempDir data_dir_; + MessageLoop message_loop_; + scoped_refptr<quota::MockQuotaManager> mock_quota_manager_; + scoped_refptr<FileSystemContext> file_system_context_; +}; + +TEST_F(FileSystemContextTest, CrackFileSystemURL) { + // Register an isolated mount point. + std::string isolated_file_system_name = "root"; + const std::string kIsolatedFileSystemID = + IsolatedContext::GetInstance()->RegisterFileSystemForPath( + kFileSystemTypeNativeLocal, + FilePath(DRIVE FPL("/test/isolated/root")), + &isolated_file_system_name); + // Register system external mount point. + ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( + "system", + kFileSystemTypeDrive, + FilePath(DRIVE FPL("/test/sys/")))); + // Register a system external mount point with the same name/id as the + // registered isolated mount point. + ASSERT_TRUE(ExternalMountPoints::GetSystemInstance()->RegisterFileSystem( + kIsolatedFileSystemID, + kFileSystemTypeRestrictedNativeLocal, + FilePath(DRIVE FPL("/test/system/isolated")))); + + struct TestCase { + // Test case values. + std::string root; + std::string type_str; + + // Expected test results. + bool expect_is_valid; + FileSystemType expect_mount_type; + FileSystemType expect_type; + const FilePath::CharType* expect_path; + bool expect_virtual_path_empty; + std::string expect_filesystem_id; + }; + + const TestCase kTestCases[] = { + // Following should not be handled by the url crackers: + { + "pers_mount", "persistent", true /* is_valid */, + kFileSystemTypePersistent, kFileSystemTypePersistent, + FPL("pers_mount/root/file"), true /* virtual path empty */, + std::string() /* filesystem id */ + }, + { + "temp_mount", "temporary", true /* is_valid */, + kFileSystemTypeTemporary, kFileSystemTypeTemporary, + FPL("temp_mount/root/file"), true /* virtual path empty */, + std::string() /* filesystem id */ + }, + // Should be cracked by isolated mount points: + { + kIsolatedFileSystemID, "isolated", true /* is_valid */, + kFileSystemTypeIsolated, kFileSystemTypeNativeLocal, + DRIVE FPL("/test/isolated/root/file"), false /* virtual path empty */, + kIsolatedFileSystemID + }, + // Should be cracked by system mount points: + { + "system", "external", true /* is_valid */, + kFileSystemTypeExternal, kFileSystemTypeDrive, + DRIVE FPL("/test/sys/root/file"), false /* virtual path empty */, + "system" + }, + { + kIsolatedFileSystemID, "external", true /* is_valid */, + kFileSystemTypeExternal, kFileSystemTypeRestrictedNativeLocal, + DRIVE FPL("/test/system/isolated/root/file"), + false /* virtual path empty */, + kIsolatedFileSystemID + }, + // Test for invalid filesystem url (made invalid by adding invalid + // filesystem type). + { + "sytem", "external", false /* is_valid */, + // The rest of values will be ignored. + kFileSystemTypeUnknown, kFileSystemTypeUnknown, FPL(""), true, + std::string() + }, + // Test for URL with non-existing filesystem id. + { + "invalid", "external", false /* is_valid */, + // The rest of values will be ignored. + kFileSystemTypeUnknown, kFileSystemTypeUnknown, FPL(""), true, + std::string() + }, + }; + + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestCases); ++i) { + const FilePath virtual_path = + FilePath::FromUTF8Unsafe(kTestCases[i].root).Append(kVirtualPathNoRoot); + + GURL raw_url = + CreateRawFileSystemURL(kTestCases[i].type_str, kTestCases[i].root); + FileSystemURL cracked_url = file_system_context()->CrackURL(raw_url); + + SCOPED_TRACE(testing::Message() << "Test case " << i << ": " + << "Cracking URL: " << raw_url); + + EXPECT_EQ(kTestCases[i].expect_is_valid, cracked_url.is_valid()); + if (!kTestCases[i].expect_is_valid) + continue; + + ExpectFileSystemURLMatches( + cracked_url, + GURL(kTestOrigin), + kTestCases[i].expect_mount_type, + kTestCases[i].expect_type, + FilePath(kTestCases[i].expect_path).NormalizePathSeparators(), + kTestCases[i].expect_virtual_path_empty ? + FilePath() : virtual_path.NormalizePathSeparators(), + kTestCases[i].expect_filesystem_id); + } + + IsolatedContext::GetInstance()->RevokeFileSystemByPath( + FilePath(DRIVE FPL("/test/isolated/root"))); + ExternalMountPoints::GetSystemInstance()->RevokeFileSystem("system"); + ExternalMountPoints::GetSystemInstance()->RevokeFileSystem( + kIsolatedFileSystemID); +} + +} // namespace + +} // namespace fileapi + diff --git a/webkit/fileapi/file_system_dir_url_request_job.cc b/webkit/fileapi/file_system_dir_url_request_job.cc index 1be9394..ec6cf23 100644 --- a/webkit/fileapi/file_system_dir_url_request_job.cc +++ b/webkit/fileapi/file_system_dir_url_request_job.cc @@ -79,7 +79,7 @@ bool FileSystemDirURLRequestJob::GetCharset(std::string* charset) { void FileSystemDirURLRequestJob::StartAsync() { if (!request_) return; - url_ = FileSystemURL(request_->url()); + url_ = file_system_context_->CrackURL(request_->url()); base::PlatformFileError error_code; FileSystemOperation* operation = GetNewOperation(&error_code); if (error_code != base::PLATFORM_FILE_OK) { diff --git a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc index 274ea49..5892171 100644 --- a/webkit/fileapi/file_system_dir_url_request_job_unittest.cc +++ b/webkit/fileapi/file_system_dir_url_request_job_unittest.cc @@ -105,9 +105,10 @@ class FileSystemDirURLRequestJobTest : public testing::Test { } FileSystemURL CreateURL(const FilePath& file_path) { - return FileSystemURL(GURL("http://remote"), - fileapi::kFileSystemTypeTemporary, - file_path); + return file_system_context_->CreateCrackedFileSystemURL( + GURL("http://remote"), + fileapi::kFileSystemTypeTemporary, + file_path); } FileSystemOperationContext* NewOperationContext() { diff --git a/webkit/fileapi/file_system_file_stream_reader_unittest.cc b/webkit/fileapi/file_system_file_stream_reader_unittest.cc index 456e30d..ad9886a 100644 --- a/webkit/fileapi/file_system_file_stream_reader_unittest.cc +++ b/webkit/fileapi/file_system_file_stream_reader_unittest.cc @@ -145,9 +145,10 @@ class FileSystemFileStreamReaderTest : public testing::Test { } FileSystemURL GetFileSystemURL(const std::string& file_name) { - return FileSystemURL(GURL(kURLOrigin), - kFileSystemTypeTemporary, - FilePath().AppendASCII(file_name)); + return file_system_context_->CreateCrackedFileSystemURL( + GURL(kURLOrigin), + kFileSystemTypeTemporary, + FilePath().AppendASCII(file_name)); } MessageLoop message_loop_; diff --git a/webkit/fileapi/file_system_mount_point_provider_unittest.cc b/webkit/fileapi/file_system_mount_point_provider_unittest.cc index 9c925a0..405c3ce 100644 --- a/webkit/fileapi/file_system_mount_point_provider_unittest.cc +++ b/webkit/fileapi/file_system_mount_point_provider_unittest.cc @@ -236,9 +236,10 @@ class FileSystemMountPointProviderTest : public testing::Test { FilePath virtual_path = FilePath(); if (type == kFileSystemTypeExternal) virtual_path = FilePath(kVirtualPath); + FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( + origin_url, type, virtual_path); FilePath returned_root_path = - provider(type)->GetFileSystemRootPathOnFileThread( - FileSystemURL(origin_url, type, virtual_path), create); + provider(type)->GetFileSystemRootPathOnFileThread(url, create); if (root_path) *root_path = returned_root_path; return !returned_root_path.empty(); diff --git a/webkit/fileapi/file_system_quota_client_unittest.cc b/webkit/fileapi/file_system_quota_client_unittest.cc index 9ca9666..24137eb 100644 --- a/webkit/fileapi/file_system_quota_client_unittest.cc +++ b/webkit/fileapi/file_system_quota_client_unittest.cc @@ -133,7 +133,8 @@ class FileSystemQuotaClientTest : public testing::Test { FileSystemType type = QuotaStorageTypeToFileSystemType(storage_type); FileSystemFileUtil* file_util = file_system_context_->GetFileUtil(type); - FileSystemURL url(GURL(origin_url), type, file_path); + FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( + GURL(origin_url), type, file_path); scoped_ptr<FileSystemOperationContext> context( CreateFileSystemOperationContext(type)); @@ -155,7 +156,8 @@ class FileSystemQuotaClientTest : public testing::Test { FileSystemFileUtil* file_util = file_system_context_-> sandbox_provider()->GetFileUtil(type); - FileSystemURL url(GURL(origin_url), type, file_path); + FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( + GURL(origin_url), type, file_path); scoped_ptr<FileSystemOperationContext> context( CreateFileSystemOperationContext(type)); diff --git a/webkit/fileapi/file_system_url.cc b/webkit/fileapi/file_system_url.cc index b69eda1..7d88f14 100644 --- a/webkit/fileapi/file_system_url.cc +++ b/webkit/fileapi/file_system_url.cc @@ -18,11 +18,10 @@ namespace fileapi { namespace { -bool CrackFileSystemURL( - const GURL& url, - GURL* origin_url, - FileSystemType* type, - FilePath* file_path) { +bool ParseFileSystemURL(const GURL& url, + GURL* origin_url, + FileSystemType* type, + FilePath* file_path) { GURL origin; FileSystemType file_system_type = kFileSystemTypeUnknown; @@ -42,6 +41,7 @@ bool CrackFileSystemURL( { kFileSystemTypeExternal, kExternalDir }, { kFileSystemTypeTest, kTestDir }, }; + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kValidTypes); ++i) { if (StartsWithASCII(inner_path, kValidTypes[i].dir, true)) { file_system_type = kValidTypes[i].type; @@ -80,25 +80,52 @@ bool CrackFileSystemURL( } // namespace FileSystemURL::FileSystemURL() - : type_(kFileSystemTypeUnknown), - mount_type_(kFileSystemTypeUnknown), - is_valid_(false) {} + : is_valid_(false), + type_(kFileSystemTypeUnknown), + mount_type_(kFileSystemTypeUnknown) { +} + +// static +FileSystemURL FileSystemURL::CreateForTest(const GURL& url) { + return FileSystemURL(url); +} + +FileSystemURL FileSystemURL::CreateForTest(const GURL& origin, + FileSystemType type, + const FilePath& path) { + return FileSystemURL(origin, type, path); +} FileSystemURL::FileSystemURL(const GURL& url) - : type_(kFileSystemTypeUnknown) { - is_valid_ = CrackFileSystemURL(url, &origin_, &type_, &virtual_path_); - MayCrackIsolatedPath(); + : type_(kFileSystemTypeUnknown), + mount_type_(kFileSystemTypeUnknown) { + is_valid_ = ParseFileSystemURL(url, &origin_, &type_, &path_); + mount_type_ = type_; } -FileSystemURL::FileSystemURL( - const GURL& origin, - FileSystemType type, - const FilePath& path) - : origin_(origin), +FileSystemURL::FileSystemURL(const GURL& origin, + FileSystemType type, + const FilePath& path) + : is_valid_(true), + origin_(origin), type_(type), - virtual_path_(path.NormalizePathSeparators()), - is_valid_(true) { - MayCrackIsolatedPath(); + mount_type_(type), + path_(path.NormalizePathSeparators()) { +} + +FileSystemURL::FileSystemURL(const GURL& origin, + FileSystemType original_type, + const FilePath& original_path, + const std::string& filesystem_id, + FileSystemType cracked_type, + const FilePath& cracked_path) + : is_valid_(true), + origin_(origin), + type_(cracked_type), + mount_type_(original_type), + path_(cracked_path.NormalizePathSeparators()), + filesystem_id_(filesystem_id), + virtual_path_(original_path.NormalizePathSeparators()) { } FileSystemURL::~FileSystemURL() {} @@ -108,13 +135,16 @@ std::string FileSystemURL::DebugString() const { return "invalid filesystem: URL"; std::ostringstream ss; ss << GetFileSystemRootURI(origin_, mount_type_); - if (!virtual_path_.empty()) + + // filesystem_id_ will be non empty for (and only for) cracked URLs. + if (!filesystem_id_.empty()) { ss << virtual_path_.value(); - if (type_ != mount_type_ || path_ != virtual_path_) { ss << " ("; ss << GetFileSystemTypeString(type_) << "@" << filesystem_id_ << ":"; ss << path_.value(); ss << ")"; + } else { + ss << path_.value(); } return ss.str(); } @@ -153,19 +183,4 @@ bool FileSystemURL::Comparator::operator()(const FileSystemURL& lhs, return lhs.path_ < rhs.path_; } -void FileSystemURL::MayCrackIsolatedPath() { - path_ = virtual_path_; - mount_type_ = type_; - if (is_valid_ && IsolatedContext::IsIsolatedType(type_)) { - // If the type is isolated, crack the path further to get the 'real' - // filesystem type and path. - is_valid_ = ExternalMountPoints::GetSystemInstance()->CrackVirtualPath( - virtual_path_, &filesystem_id_, &type_, &path_); - if (is_valid_) - return; - is_valid_ = IsolatedContext::GetInstance()->CrackVirtualPath( - virtual_path_, &filesystem_id_, &type_, &path_); - } -} - } // namespace fileapi diff --git a/webkit/fileapi/file_system_url.h b/webkit/fileapi/file_system_url.h index 0d4bb65..0245d94 100644 --- a/webkit/fileapi/file_system_url.h +++ b/webkit/fileapi/file_system_url.h @@ -18,30 +18,49 @@ namespace fileapi { // A class representing a filesystem URL which consists of origin URL, // type and an internal path used inside the filesystem. // -// When a FileSystemURL instance is created for regular sandbox file systems +// When a FileSystemURL instance is created for a GURL (for filesystem: scheme), // each accessor method would return following values: // // Example: For a URL 'filesystem:http://foo.com/temporary/foo/bar': // origin() returns 'http://foo.com', // type() and mount_type() return kFileSystemTypeTemporary, -// path() and virtual_path() return 'foo/bar', and -// filesystem_id() returns an empty string. +// path() returns 'foo/bar', // -// path() and virtual_path() usually return the same value, but they -// have different values if an instance is created for Isolated or External -// FileSystem URL, for which we may mount different paths from its exposed -// virtual paths. +// All other accessors return empty or invalid value. +// +// FileSystemURL can also be created to represent a 'cracked' filesystem URL if +// the original URL's type/path is pointing to a mount point which can be +// further resolved to a lower filesystem type/path. // // Example: Assume a path '/media/removable' is mounted at mount name // 'mount_name' with type kFileSystemTypeFoo as an external file system. -// For a URL 'filesystem:http://bar.com/external/mount_name/foo/bar': +// +// The original URL would look like: +// 'filesystem:http://bar.com/external/mount_name/foo/bar': +// +// FileSystemURL('http://bar.com', +// kFileSystemTypeExternal, +// 'mount_name/foo/bar' +// 'mount_name', +// kFileSystemTypeFoo, +// '/media/removable/foo/bar'); +// would create a FileSystemURL whose accessors return: +// // origin() returns 'http://bar.com', // type() returns the kFileSystemTypeFoo, // path() returns '/media/removable/foo/bar', -// virtual_path() returns 'mount_name/foo/bar', +// +// Additionally, following accessors would return valid values: // filesystem_id() returns 'mount_name', and +// virtual_path() returns 'mount_name/foo/bar', // mount_type() returns kFileSystemTypeExternal. // +// It is imposible to directly create a valid FileSystemURL instance (except by +// using CreatedForTest methods, which should not be used in production code). +// To get a valid FileSystemURL, one of the following methods can be used: +// <Friend>::CrackURL, <Friend>::CreateCrackedFileSystemURL, where <Friend> is +// one of the friended classes. +// // TODO(ericu): Look into making path() [and all FileSystem API virtual // paths] just an std::string, to prevent platform-specific FilePath behavior // from getting invoked by accident. Currently the FilePath returned here needs @@ -51,12 +70,15 @@ namespace fileapi { class WEBKIT_STORAGE_EXPORT FileSystemURL { public: FileSystemURL(); - explicit FileSystemURL(const GURL& filesystem_url); - FileSystemURL(const GURL& origin, - FileSystemType type, - const FilePath& internal_path); ~FileSystemURL(); + // Methods for creating FileSystemURL without attempting to crack them. + // Should be used only in tests. + static FileSystemURL CreateForTest(const GURL& url); + static FileSystemURL CreateForTest(const GURL& origin, + FileSystemType type, + const FilePath& path); + // Returns true if this instance represents a valid FileSystem URL. bool is_valid() const { return is_valid_; } @@ -75,12 +97,10 @@ class WEBKIT_STORAGE_EXPORT FileSystemURL { // TODO(kinuko): this must return std::string. const FilePath& virtual_path() const { return virtual_path_; } - // Returns the filesystem ID/name for isolated/external file system URLs. + // Returns the filesystem ID/mount name for isolated/external filesystem URLs. // See the class comment for details. const std::string& filesystem_id() const { return filesystem_id_; } - // Returns the public file system type of this URL. - // See the class comment for details. FileSystemType mount_type() const { return mount_type_; } std::string DebugString() const; @@ -89,9 +109,9 @@ class WEBKIT_STORAGE_EXPORT FileSystemURL { // This creates a new FileSystemURL, copies all fields of this instance // to that one, resets the path_ to the given |path| and resets the // virtual_path to *empty*. - // Note that the resulting FileSystemURL always has an empty virtual_path - // (as virtual_path is meant to represent the path that is given in the - // original filesystem: URL in the current implementation). + // Note that the resulting FileSystemURL loses original URL information + // if it was a cracked filesystem; i.e. virtual_path and mount_type will + // be set to empty values. FileSystemURL WithPath(const FilePath& path) const; // Returns true if this URL is a strict parent of the |child|. @@ -104,18 +124,33 @@ class WEBKIT_STORAGE_EXPORT FileSystemURL { }; private: - void MayCrackIsolatedPath(); + friend class FileSystemContext; + friend class ExternalMountPoints; + friend class IsolatedContext; + + explicit FileSystemURL(const GURL& filesystem_url); + FileSystemURL(const GURL& origin, + FileSystemType type, + const FilePath& internal_path); + // Creates a cracked FileSystemURL. + FileSystemURL(const GURL& origin, + FileSystemType original_type, + const FilePath& original_path, + const std::string& filesystem_id, + FileSystemType cracked_type, + const FilePath& cracked_path); + + bool is_valid_; GURL origin_; FileSystemType type_; + FileSystemType mount_type_; FilePath path_; - // For isolated filesystem. + // Values specific to cracked URLs. std::string filesystem_id_; FilePath virtual_path_; - FileSystemType mount_type_; - bool is_valid_; }; typedef std::set<FileSystemURL, FileSystemURL::Comparator> FileSystemURLSet; diff --git a/webkit/fileapi/file_system_url_request_job.cc b/webkit/fileapi/file_system_url_request_job.cc index 0726bde..51d3272 100644 --- a/webkit/fileapi/file_system_url_request_job.cc +++ b/webkit/fileapi/file_system_url_request_job.cc @@ -156,7 +156,7 @@ void FileSystemURLRequestJob::StartAsync() { if (!request_) return; DCHECK(!reader_.get()); - url_ = FileSystemURL(request_->url()); + url_ = file_system_context_->CrackURL(request_->url()); base::PlatformFileError error_code; FileSystemOperation* operation = file_system_context_->CreateFileSystemOperation(url_, &error_code); diff --git a/webkit/fileapi/file_system_url_request_job_unittest.cc b/webkit/fileapi/file_system_url_request_job_unittest.cc index 0efb40a..2605d76 100644 --- a/webkit/fileapi/file_system_url_request_job_unittest.cc +++ b/webkit/fileapi/file_system_url_request_job_unittest.cc @@ -133,9 +133,10 @@ class FileSystemURLRequestJobTest : public testing::Test { void CreateDirectory(const base::StringPiece& dir_name) { FileSystemFileUtil* file_util = file_system_context_-> sandbox_provider()->GetFileUtil(kFileSystemTypeTemporary); - FileSystemURL url(GURL("http://remote"), - kFileSystemTypeTemporary, - FilePath().AppendASCII(dir_name)); + FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( + GURL("http://remote"), + kFileSystemTypeTemporary, + FilePath().AppendASCII(dir_name)); FileSystemOperationContext context(file_system_context_); context.set_allowed_bytes_growth(1024); @@ -151,9 +152,10 @@ class FileSystemURLRequestJobTest : public testing::Test { const char* buf, int buf_size) { FileSystemFileUtil* file_util = file_system_context_-> sandbox_provider()->GetFileUtil(kFileSystemTypeTemporary); - FileSystemURL url(GURL("http://remote"), - kFileSystemTypeTemporary, - FilePath().AppendASCII(file_name)); + FileSystemURL url = file_system_context_->CreateCrackedFileSystemURL( + GURL("http://remote"), + kFileSystemTypeTemporary, + FilePath().AppendASCII(file_name)); FileSystemOperationContext context(file_system_context_); context.set_allowed_bytes_growth(1024); diff --git a/webkit/fileapi/file_system_url_unittest.cc b/webkit/fileapi/file_system_url_unittest.cc index c1c01a3..58a4b7a 100644 --- a/webkit/fileapi/file_system_url_unittest.cc +++ b/webkit/fileapi/file_system_url_unittest.cc @@ -26,7 +26,24 @@ namespace fileapi { namespace { FileSystemURL CreateFileSystemURL(const std::string& url_string) { - return FileSystemURL(GURL(url_string)); + FileSystemURL url = FileSystemURL::CreateForTest(GURL(url_string)); + switch (url.type()) { + case kFileSystemTypeExternal: + return ExternalMountPoints::GetSystemInstance()-> + CreateCrackedFileSystemURL(url.origin(), url.type(), url.path()); + case kFileSystemTypeIsolated: + return IsolatedContext::GetInstance()->CreateCrackedFileSystemURL( + url.origin(), url.type(), url.path()); + default: + return url; + } +} + +FileSystemURL CreateExternalFileSystemURL(const GURL& origin, + FileSystemType type, + const FilePath& path) { + return ExternalMountPoints::GetSystemInstance()->CreateCrackedFileSystemURL( + origin, type, path); } std::string NormalizedUTF8Path(const FilePath& path) { @@ -108,7 +125,8 @@ TEST(FileSystemURLTest, CompareURLs) { for (size_t j = 0; j < arraysize(urls); ++j) { SCOPED_TRACE(testing::Message() << i << " < " << j); EXPECT_EQ(urls[i] < urls[j], - compare(FileSystemURL(urls[i]), FileSystemURL(urls[j]))); + compare(FileSystemURL::CreateForTest(urls[i]), + FileSystemURL::CreateForTest(urls[j]))); } } @@ -129,7 +147,7 @@ TEST(FileSystemURLTest, WithPath) { FPL("dir a/dir b/file 2"), }; - const FileSystemURL base = FileSystemURL(kURL); + const FileSystemURL base = FileSystemURL::CreateForTest(kURL); for (size_t i = 0; i < arraysize(paths); ++i) { const FileSystemURL url = base.WithPath(FilePath(paths[i])); EXPECT_EQ(paths[i], url.path().value()); @@ -153,7 +171,7 @@ TEST(FileSystemURLTest, WithPathForExternal) { FPL("dir a/dir b/file 2"), }; - const FileSystemURL base = FileSystemURL( + const FileSystemURL base = FileSystemURL::CreateForTest( GURL("http://example.com/"), kFileSystemTypeExternal, kVirtualRoot.Append(kBasePath)); @@ -216,7 +234,8 @@ TEST(FileSystemURLTest, DebugString) { const GURL kOrigin("http://example.com"); const FilePath kPath(FPL("dir/file")); - const FileSystemURL kURL1(kOrigin, kFileSystemTypeTemporary, kPath); + const FileSystemURL kURL1 = FileSystemURL::CreateForTest( + kOrigin, kFileSystemTypeTemporary, kPath); EXPECT_EQ("filesystem:http://example.com/temporary/" + NormalizedUTF8Path(kPath), kURL1.DebugString()); @@ -225,8 +244,10 @@ TEST(FileSystemURLTest, DebugString) { ScopedExternalFileSystem scoped_fs("foo", kFileSystemTypeNativeLocal, kRoot.NormalizePathSeparators()); - const FileSystemURL kURL2(kOrigin, kFileSystemTypeExternal, - scoped_fs.GetVirtualRootPath().Append(kPath)); + const FileSystemURL kURL2(CreateExternalFileSystemURL( + kOrigin, + kFileSystemTypeExternal, + scoped_fs.GetVirtualRootPath().Append(kPath))); EXPECT_EQ("filesystem:http://example.com/external/" + NormalizedUTF8Path(scoped_fs.GetVirtualRootPath().Append(kPath)) + " (NativeLocal@foo:" + diff --git a/webkit/fileapi/isolated_context.cc b/webkit/fileapi/isolated_context.cc index 1433e72..fe1aec0 100644 --- a/webkit/fileapi/isolated_context.cc +++ b/webkit/fileapi/isolated_context.cc @@ -12,6 +12,7 @@ #include "base/string_number_conversions.h" #include "base/string_util.h" #include "base/stringprintf.h" +#include "webkit/fileapi/file_system_url.h" namespace fileapi { @@ -225,6 +226,10 @@ std::string IsolatedContext::RegisterFileSystemForPath( return filesystem_id; } +bool IsolatedContext::HandlesFileSystemMountType(FileSystemType type) const { + return type == kFileSystemTypeIsolated; +} + bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { base::AutoLock locker(lock_); return UnregisterFileSystem(filesystem_id); @@ -292,6 +297,32 @@ bool IsolatedContext::CrackVirtualPath(const FilePath& virtual_path, return true; } +FileSystemURL IsolatedContext::CrackURL(const GURL& url) const { + FileSystemURL filesystem_url = FileSystemURL(url); + if (!filesystem_url.is_valid()) + return FileSystemURL(); + return CreateCrackedFileSystemURL(filesystem_url.origin(), + filesystem_url.mount_type(), + filesystem_url.path()); +} + +FileSystemURL IsolatedContext::CreateCrackedFileSystemURL( + const GURL& origin, + FileSystemType type, + const FilePath& path) const { + if (!HandlesFileSystemMountType(type)) + return FileSystemURL(); + + std::string mount_name; + FileSystemType cracked_type; + FilePath cracked_path; + if (!CrackVirtualPath(path, &mount_name, &cracked_type, &cracked_path)) + return FileSystemURL(); + + return FileSystemURL(origin, type, path, + mount_name, cracked_type, cracked_path); +} + void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { base::AutoLock locker(lock_); FilePath path(path_in.NormalizePathSeparators()); diff --git a/webkit/fileapi/isolated_context.h b/webkit/fileapi/isolated_context.h index 63cab56..d679bc3 100644 --- a/webkit/fileapi/isolated_context.h +++ b/webkit/fileapi/isolated_context.h @@ -20,6 +20,10 @@ #include "webkit/storage/webkit_storage_export.h" namespace fileapi { +class FileSystemURL; +} + +namespace fileapi { // Manages isolated filesystem mount points which have no well-known names // and are identified by a string 'filesystem ID', which usually just looks @@ -98,15 +102,6 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext : public MountPoints { const FilePath& path, std::string* register_name); - // MountPoints override. - virtual bool RevokeFileSystem(const std::string& filesystem_id) OVERRIDE; - virtual bool GetRegisteredPath(const std::string& filesystem_id, - FilePath* path) const OVERRIDE; - virtual bool CrackVirtualPath(const FilePath& virtual_path, - std::string* filesystem_id, - FileSystemType* type, - FilePath* path) const OVERRIDE; - // Revokes all filesystem(s) registered for the given path. // This is assumed to be called when the registered path becomes // globally invalid, e.g. when a device for the path is detached. @@ -134,6 +129,21 @@ class WEBKIT_STORAGE_EXPORT IsolatedContext : public MountPoints { bool GetDraggedFileInfo(const std::string& filesystem_id, std::vector<MountPointInfo>* files) const; + // MountPoints overrides. + virtual bool HandlesFileSystemMountType(FileSystemType type) const OVERRIDE; + virtual bool RevokeFileSystem(const std::string& filesystem_id) OVERRIDE; + virtual bool GetRegisteredPath(const std::string& filesystem_id, + FilePath* path) const OVERRIDE; + virtual bool CrackVirtualPath(const FilePath& virtual_path, + std::string* filesystem_id, + FileSystemType* type, + FilePath* path) const OVERRIDE; + virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE; + virtual FileSystemURL CreateCrackedFileSystemURL( + const GURL& origin, + FileSystemType type, + const FilePath& path) const OVERRIDE; + // Returns the virtual root path that looks like /<filesystem_id>. FilePath CreateVirtualRootPath(const std::string& filesystem_id) const; diff --git a/webkit/fileapi/isolated_context_unittest.cc b/webkit/fileapi/isolated_context_unittest.cc index bf36df9..4cb7a84 100644 --- a/webkit/fileapi/isolated_context_unittest.cc +++ b/webkit/fileapi/isolated_context_unittest.cc @@ -7,6 +7,7 @@ #include "base/basictypes.h" #include "base/logging.h" #include "testing/gtest/include/gtest/gtest.h" +#include "webkit/fileapi/file_system_url.h" #include "webkit/fileapi/isolated_context.h" #define FPL(x) FILE_PATH_LITERAL(x) @@ -189,7 +190,7 @@ TEST_F(IsolatedContextTest, CrackWithRelativePaths) { .AppendASCII(names_[i]).Append(relatives[j].path); std::string cracked_id; FilePath cracked_path; - FileSystemType cracked_type; + FileSystemType cracked_type; if (!relatives[j].valid) { ASSERT_FALSE(isolated_context()->CrackVirtualPath( virtual_path, &cracked_id, &cracked_type, &cracked_path)); @@ -206,6 +207,51 @@ TEST_F(IsolatedContextTest, CrackWithRelativePaths) { } } +TEST_F(IsolatedContextTest, CrackURLWithRelativePaths) { + const struct { + FilePath::StringType path; + bool valid; + } relatives[] = { + { FPL("foo"), true }, + { FPL("foo/bar"), true }, + { FPL(".."), false }, + { FPL("foo/.."), false }, + { FPL("foo/../bar"), false }, +#if defined(FILE_PATH_USES_WIN_SEPARATORS) +# define SHOULD_FAIL_WITH_WIN_SEPARATORS false +#else +# define SHOULD_FAIL_WITH_WIN_SEPARATORS true +#endif + { FPL("foo\\..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, + { FPL("foo/..\\baz"), SHOULD_FAIL_WITH_WIN_SEPARATORS }, + }; + + for (size_t i = 0; i < arraysize(kTestPaths); ++i) { + for (size_t j = 0; j < ARRAYSIZE_UNSAFE(relatives); ++j) { + SCOPED_TRACE(testing::Message() << "Testing " + << kTestPaths[i].value() << " " << relatives[j].path); + FilePath virtual_path = isolated_context()->CreateVirtualRootPath(id_) + .AppendASCII(names_[i]).Append(relatives[j].path); + + FileSystemURL cracked = isolated_context()->CreateCrackedFileSystemURL( + GURL("http://chromium.org"), kFileSystemTypeIsolated, virtual_path); + + ASSERT_EQ(relatives[j].valid, cracked.is_valid()); + + if (!relatives[j].valid) + continue; + ASSERT_EQ(GURL("http://chromium.org"), cracked.origin()); + ASSERT_EQ(kTestPaths[i].Append(relatives[j].path) + .NormalizePathSeparators().value(), + cracked.path().value()); + ASSERT_EQ(virtual_path.NormalizePathSeparators(), cracked.virtual_path()); + ASSERT_EQ(id_, cracked.filesystem_id()); + ASSERT_EQ(kFileSystemTypeDragged, cracked.type()); + ASSERT_EQ(kFileSystemTypeIsolated, cracked.mount_type()); + } + } +} + TEST_F(IsolatedContextTest, TestWithVirtualRoot) { std::string cracked_id; FilePath cracked_path; @@ -227,4 +273,32 @@ TEST_F(IsolatedContextTest, TestWithVirtualRoot) { virtual_path, &cracked_id, NULL, &cracked_path)); } +TEST_F(IsolatedContextTest, CanHandleURL) { + const GURL test_origin("http://chromium.org"); + const FilePath test_path(FPL("/mount")); + + // Should handle isolated file system. + EXPECT_TRUE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeIsolated)); + + // Shouldn't handle the rest. + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeExternal)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeTemporary)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypePersistent)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeTest)); + // Not even if it's isolated subtype. + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeNativeLocal)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeDragged)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeNativeMedia)); + EXPECT_FALSE(isolated_context()->HandlesFileSystemMountType( + fileapi::kFileSystemTypeDeviceMedia)); +} + } // namespace fileapi diff --git a/webkit/fileapi/isolated_file_util_unittest.cc b/webkit/fileapi/isolated_file_util_unittest.cc index 57ef51a..949b244 100644 --- a/webkit/fileapi/isolated_file_util_unittest.cc +++ b/webkit/fileapi/isolated_file_util_unittest.cc @@ -125,9 +125,10 @@ class IsolatedFileUtilTest : public testing::Test { FileSystemURL GetFileSystemURL(const FilePath& path) const { FilePath virtual_path = isolated_context()->CreateVirtualRootPath( filesystem_id()).Append(path); - return FileSystemURL(GURL("http://example.com"), - kFileSystemTypeIsolated, - virtual_path); + return file_system_context_->CreateCrackedFileSystemURL( + GURL("http://example.com"), + kFileSystemTypeIsolated, + virtual_path); } FileSystemURL GetOtherFileSystemURL(const FilePath& path) { diff --git a/webkit/fileapi/local_file_system_test_helper.cc b/webkit/fileapi/local_file_system_test_helper.cc index d18249f..a71a799 100644 --- a/webkit/fileapi/local_file_system_test_helper.cc +++ b/webkit/fileapi/local_file_system_test_helper.cc @@ -49,8 +49,8 @@ void LocalFileSystemTestOriginHelper::SetUp( // Prepare the origin's root directory. file_system_context_->GetMountPointProvider(type_)-> - GetFileSystemRootPathOnFileThread( - FileSystemURL(origin_, type_, FilePath()), true /* create */); + GetFileSystemRootPathOnFileThread(CreateURL(FilePath()), + true /* create */); // Initialize the usage cache file. FilePath usage_cache_path = GetUsageCachePath(); @@ -77,8 +77,8 @@ void LocalFileSystemTestOriginHelper::SetUp( // Prepare the origin's root directory. FileSystemMountPointProvider* mount_point_provider = file_system_context_->GetMountPointProvider(type_); - mount_point_provider->GetFileSystemRootPathOnFileThread( - FileSystemURL(origin_, type_, FilePath()), true /* create */); + mount_point_provider->GetFileSystemRootPathOnFileThread(CreateURL(FilePath()), + true /* create */); // Initialize the usage cache file. FilePath usage_cache_path = GetUsageCachePath(); @@ -93,8 +93,7 @@ void LocalFileSystemTestOriginHelper::TearDown() { FilePath LocalFileSystemTestOriginHelper::GetOriginRootPath() const { return file_system_context_->GetMountPointProvider(type_)-> - GetFileSystemRootPathOnFileThread( - FileSystemURL(origin_, type_, FilePath()), false); + GetFileSystemRootPathOnFileThread(CreateURL(FilePath()), false); } FilePath LocalFileSystemTestOriginHelper::GetLocalPath(const FilePath& path) { @@ -120,7 +119,7 @@ FilePath LocalFileSystemTestOriginHelper::GetUsageCachePath() const { FileSystemURL LocalFileSystemTestOriginHelper::CreateURL(const FilePath& path) const { - return FileSystemURL(origin_, type_, path); + return file_system_context_->CreateCrackedFileSystemURL(origin_, type_, path); } base::PlatformFileError LocalFileSystemTestOriginHelper::SameFileUtilCopy( diff --git a/webkit/fileapi/media/native_media_file_util_unittest.cc b/webkit/fileapi/media/native_media_file_util_unittest.cc index 6055ed1..66bffd3 100644 --- a/webkit/fileapi/media/native_media_file_util_unittest.cc +++ b/webkit/fileapi/media/native_media_file_util_unittest.cc @@ -135,6 +135,13 @@ class NativeMediaFileUtilTest : public testing::Test { return file_system_context_.get(); } + FileSystemURL CreateURL(const FilePath::CharType* test_case_path) { + return file_system_context_->CreateCrackedFileSystemURL( + origin(), + fileapi::kFileSystemTypeIsolated, + GetVirtualPath(test_case_path)); + } + IsolatedContext* isolated_context() { return IsolatedContext::GetInstance(); } @@ -143,6 +150,12 @@ class NativeMediaFileUtilTest : public testing::Test { return data_dir_.path().Append(FPL("Media Directory")); } + FilePath GetVirtualPath(const FilePath::CharType* test_case_path) { + return FilePath::FromUTF8Unsafe(filesystem_id_). + Append(FPL("Media Directory")). + Append(FilePath(test_case_path)); + } + FileSystemFileUtil* file_util() { return file_util_; } @@ -177,8 +190,7 @@ TEST_F(NativeMediaFileUtilTest, DirectoryExistsAndFileExistsFiltering) { arraysize(kFilteringTestCases)); for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); FileSystemOperation* operation = NewOperation(url); base::PlatformFileError expectation = @@ -205,7 +217,7 @@ TEST_F(NativeMediaFileUtilTest, ReadDirectoryFiltering) { arraysize(kFilteringTestCases)); std::set<FilePath::StringType> content; - FileSystemURL url(origin(), type(), root_path()); + FileSystemURL url = CreateURL(FPL("")); bool completed = false; NewOperation(url)->ReadDirectory( url, base::Bind(&DidReadDirectory, &content, &completed)); @@ -226,11 +238,10 @@ TEST_F(NativeMediaFileUtilTest, CreateFileAndCreateDirectoryFiltering) { // pre-existing. Though the result should be the same. for (int loop_count = 0; loop_count < 2; ++loop_count) { for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "CreateFileAndCreateDirectoryFiltering run %d, test %" PRIuS, @@ -254,7 +265,7 @@ TEST_F(NativeMediaFileUtilTest, CreateFileAndCreateDirectoryFiltering) { TEST_F(NativeMediaFileUtilTest, CopySourceFiltering) { FilePath dest_path = root_path().AppendASCII("dest"); - FileSystemURL dest_url(origin(), type(), dest_path); + FileSystemURL dest_url = CreateURL(FPL("dest")); // Run the loop twice. The first run has no source files. The second run does. for (int loop_count = 0; loop_count < 2; ++loop_count) { @@ -269,11 +280,10 @@ TEST_F(NativeMediaFileUtilTest, CopySourceFiltering) { ASSERT_TRUE(file_util::Delete(dest_path, true)); ASSERT_TRUE(file_util::CreateDirectory(dest_path)); - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "CopySourceFiltering run %d test %" PRIuS, loop_count, i); @@ -308,7 +318,7 @@ TEST_F(NativeMediaFileUtilTest, CopyDestFiltering) { // Always create a dummy source data file. FilePath src_path = root_path().AppendASCII("foo.jpg"); - FileSystemURL src_url(origin(), type(), src_path); + FileSystemURL src_url = CreateURL(FPL("foo.jpg")); static const char kDummyData[] = "dummy"; ASSERT_TRUE(file_util::WriteFile(src_path, kDummyData, strlen(kDummyData))); @@ -320,11 +330,10 @@ TEST_F(NativeMediaFileUtilTest, CopyDestFiltering) { // unused. continue; } - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "CopyDestFiltering run %d test %" PRIuS, loop_count, i); @@ -361,7 +370,7 @@ TEST_F(NativeMediaFileUtilTest, CopyDestFiltering) { TEST_F(NativeMediaFileUtilTest, MoveSourceFiltering) { FilePath dest_path = root_path().AppendASCII("dest"); - FileSystemURL dest_url(origin(), type(), dest_path); + FileSystemURL dest_url = CreateURL(FPL("dest")); // Run the loop twice. The first run has no source files. The second run does. for (int loop_count = 0; loop_count < 2; ++loop_count) { @@ -376,11 +385,10 @@ TEST_F(NativeMediaFileUtilTest, MoveSourceFiltering) { ASSERT_TRUE(file_util::Delete(dest_path, true)); ASSERT_TRUE(file_util::CreateDirectory(dest_path)); - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "MoveSourceFiltering run %d test %" PRIuS, loop_count, i); @@ -424,16 +432,15 @@ TEST_F(NativeMediaFileUtilTest, MoveDestFiltering) { // Create the source file for every test case because it might get moved. FilePath src_path = root_path().AppendASCII("foo.jpg"); - FileSystemURL src_url(origin(), type(), src_path); + FileSystemURL src_url = CreateURL(FPL("foo.jpg")); static const char kDummyData[] = "dummy"; ASSERT_TRUE( file_util::WriteFile(src_path, kDummyData, strlen(kDummyData))); - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "MoveDestFiltering run %d test %" PRIuS, loop_count, i); @@ -477,11 +484,10 @@ TEST_F(NativeMediaFileUtilTest, GetMetadataFiltering) { arraysize(kFilteringTestCases)); } for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "GetMetadataFiltering run %d test %" PRIuS, loop_count, i); @@ -509,11 +515,10 @@ TEST_F(NativeMediaFileUtilTest, RemoveFiltering) { arraysize(kFilteringTestCases)); } for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "RemoveFiltering run %d test %" PRIuS, loop_count, i); @@ -538,11 +543,10 @@ TEST_F(NativeMediaFileUtilTest, TruncateFiltering) { arraysize(kFilteringTestCases)); } for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "TruncateFiltering run %d test %" PRIuS, loop_count, i); @@ -572,11 +576,10 @@ TEST_F(NativeMediaFileUtilTest, TouchFileFiltering) { arraysize(kFilteringTestCases)); } for (size_t i = 0; i < arraysize(kFilteringTestCases); ++i) { - FileSystemURL root_url(origin(), type(), root_path()); + FileSystemURL root_url = CreateURL(FPL("")); FileSystemOperation* operation = NewOperation(root_url); - FilePath path = root_path().Append(kFilteringTestCases[i].path); - FileSystemURL url(origin(), type(), path); + FileSystemURL url = CreateURL(kFilteringTestCases[i].path); std::string test_name = base::StringPrintf( "TouchFileFiltering run %d test %" PRIuS, loop_count, i); diff --git a/webkit/fileapi/mount_points.h b/webkit/fileapi/mount_points.h index 0cfb57b..27df0f2 100644 --- a/webkit/fileapi/mount_points.h +++ b/webkit/fileapi/mount_points.h @@ -16,6 +16,10 @@ class GURL; namespace fileapi { +class FileSystemURL; +} + +namespace fileapi { // Represents a set of mount points for File API. class WEBKIT_STORAGE_EXPORT MountPoints { @@ -46,6 +50,23 @@ class WEBKIT_STORAGE_EXPORT MountPoints { // TODO(kinuko): Probably this should be rather named RevokeMountPoint. virtual bool RevokeFileSystem(const std::string& mount_name) = 0; + // Returns true if the MountPoints implementation handles filesystems with + // the given mount type. + virtual bool HandlesFileSystemMountType(FileSystemType type) const = 0; + + // Same as CreateCrackedFileSystemURL, but cracks FileSystemURL created + // from |url|. + virtual FileSystemURL CrackURL(const GURL& url) const = 0; + + // Creates a FileSystemURL with the given origin, type and path and tries to + // crack it as a part of one of the registered mount points. + // If the the URL is not valid or does not belong to any of the mount points + // registered in this context, returns empty, invalid FileSystemURL. + virtual FileSystemURL CreateCrackedFileSystemURL( + const GURL& origin, + fileapi::FileSystemType type, + const FilePath& path) const = 0; + // Returns the mount point root path registered for a given |mount_name|. // Returns false if the given |mount_name| is not valid. virtual bool GetRegisteredPath(const std::string& mount_name, diff --git a/webkit/fileapi/sandbox_mount_point_provider.cc b/webkit/fileapi/sandbox_mount_point_provider.cc index aaf3d43..3f71d48 100644 --- a/webkit/fileapi/sandbox_mount_point_provider.cc +++ b/webkit/fileapi/sandbox_mount_point_provider.cc @@ -429,7 +429,8 @@ int64 SandboxMountPointProvider::GetOriginUsageOnFileThread( FileSystemUsageCache::Delete(usage_file_path); FileSystemOperationContext context(file_system_context); - FileSystemURL url(origin_url, type, FilePath()); + FileSystemURL url = file_system_context->CreateCrackedFileSystemURL( + origin_url, type, FilePath()); scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( sandbox_file_util_->CreateFileEnumerator(&context, url, true)); diff --git a/webkit/fileapi/syncable/canned_syncable_file_system.cc b/webkit/fileapi/syncable/canned_syncable_file_system.cc index e960959..0f72c17 100644 --- a/webkit/fileapi/syncable/canned_syncable_file_system.cc +++ b/webkit/fileapi/syncable/canned_syncable_file_system.cc @@ -13,6 +13,7 @@ #include "base/task_runner_util.h" #include "testing/gtest/include/gtest/gtest.h" #include "webkit/blob/mock_blob_url_request_context.h" +#include "webkit/fileapi/external_mount_points.h" #include "webkit/fileapi/file_system_context.h" #include "webkit/fileapi/file_system_operation_context.h" #include "webkit/fileapi/file_system_task_runners.h" @@ -229,7 +230,9 @@ void CannedSyncableFileSystem::TearDown() { FileSystemURL CannedSyncableFileSystem::URL(const std::string& path) const { EXPECT_TRUE(is_filesystem_set_up_); EXPECT_TRUE(is_filesystem_opened_); - return FileSystemURL(GURL(root_url_.spec() + path)); + + GURL url(root_url_.spec() + path); + return file_system_context_->CrackURL(url); } PlatformFileError CannedSyncableFileSystem::OpenFileSystem() { diff --git a/webkit/fileapi/syncable/local_file_sync_status_unittest.cc b/webkit/fileapi/syncable/local_file_sync_status_unittest.cc index a899e3c..c78237f 100644 --- a/webkit/fileapi/syncable/local_file_sync_status_unittest.cc +++ b/webkit/fileapi/syncable/local_file_sync_status_unittest.cc @@ -20,7 +20,7 @@ const char kOther1[] = "filesystem:http://foo.com/test/dir b"; const char kOther2[] = "filesystem:http://foo.com/temporary/dir a"; FileSystemURL URL(const char* spec) { - return FileSystemURL(GURL(spec)); + return FileSystemURL::CreateForTest((GURL(spec))); } } // namespace diff --git a/webkit/fileapi/syncable/syncable_file_system_util.cc b/webkit/fileapi/syncable/syncable_file_system_util.cc index 21652d0..e8d87d9 100644 --- a/webkit/fileapi/syncable/syncable_file_system_util.cc +++ b/webkit/fileapi/syncable/syncable_file_system_util.cc @@ -34,9 +34,10 @@ GURL GetSyncableFileSystemRootURI(const GURL& origin, FileSystemURL CreateSyncableFileSystemURL(const GURL& origin, const std::string& service_name, const FilePath& path) { - return FileSystemURL(origin, - kFileSystemTypeExternal, - FilePath::FromUTF8Unsafe(service_name).Append(path)); + return ExternalMountPoints::GetSystemInstance()->CreateCrackedFileSystemURL( + origin, + kFileSystemTypeExternal, + FilePath::FromUTF8Unsafe(service_name).Append(path)); } bool SerializeSyncableFileSystemURL(const FileSystemURL& url, @@ -55,12 +56,14 @@ bool DeserializeSyncableFileSystemURL( DCHECK(serialized_url.find('\\') == std::string::npos); #endif // FILE_PATH_USES_WIN_SEPARATORS - const FileSystemURL deserialized_url = FileSystemURL(GURL(serialized_url)); - if (!deserialized_url.is_valid() || - deserialized_url.type() != kFileSystemTypeSyncable) + FileSystemURL deserialized = + ExternalMountPoints::GetSystemInstance()->CrackURL(GURL(serialized_url)); + if (!deserialized.is_valid() || + deserialized.type() != kFileSystemTypeSyncable) { return false; + } - *url = deserialized_url; + *url = deserialized; return true; } diff --git a/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc b/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc index 356ff53..91b0baa 100644 --- a/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc +++ b/webkit/fileapi/syncable/syncable_file_system_util_unittest.cc @@ -28,7 +28,7 @@ const char kServiceName[] = "service"; const FilePath::CharType kPath[] = FILE_PATH_LITERAL("dir/file"); FileSystemURL CreateFileSystemURL(const std::string& url) { - return FileSystemURL(GURL(url)); + return ExternalMountPoints::GetSystemInstance()->CrackURL(GURL(url)); } FilePath CreateNormalizedFilePath(const FilePath::CharType* path) { diff --git a/webkit/fileapi/upload_file_system_file_element_reader.cc b/webkit/fileapi/upload_file_system_file_element_reader.cc index 212640a..6e5f47e 100644 --- a/webkit/fileapi/upload_file_system_file_element_reader.cc +++ b/webkit/fileapi/upload_file_system_file_element_reader.cc @@ -41,7 +41,9 @@ int UploadFileSystemFileElementReader::Init( // Initialize the stream reader and the length. stream_reader_.reset( file_system_context_->CreateFileStreamReader( - FileSystemURL(url_), range_offset_, expected_modification_time_)); + file_system_context_->CrackURL(url_), + range_offset_, + expected_modification_time_)); DCHECK(stream_reader_); const int result = stream_reader_->GetLength( diff --git a/webkit/fileapi/upload_file_system_file_element_reader_unittest.cc b/webkit/fileapi/upload_file_system_file_element_reader_unittest.cc index ba9ce01..40128fe 100644 --- a/webkit/fileapi/upload_file_system_file_element_reader_unittest.cc +++ b/webkit/fileapi/upload_file_system_file_element_reader_unittest.cc @@ -79,9 +79,11 @@ class UploadFileSystemFileElementReaderTest : public testing::Test { const char* buf, int buf_size, base::Time* modification_time) { - fileapi::FileSystemURL url(GURL(kFileSystemURLOrigin), - kFileSystemType, - FilePath().AppendASCII(filename)); + fileapi::FileSystemURL url = + file_system_context_->CreateCrackedFileSystemURL( + GURL(kFileSystemURLOrigin), + kFileSystemType, + FilePath().AppendASCII(filename)); fileapi::FileSystemFileUtil* file_util = file_system_context_->GetFileUtil(kFileSystemType); diff --git a/webkit/tools/test_shell/simple_file_system.cc b/webkit/tools/test_shell/simple_file_system.cc index 8bfc0b7..aace922 100644 --- a/webkit/tools/test_shell/simple_file_system.cc +++ b/webkit/tools/test_shell/simple_file_system.cc @@ -123,8 +123,8 @@ void SimpleFileSystem::DeleteFileSystem( void SimpleFileSystem::move( const WebURL& src_path, const WebURL& dest_path, WebFileSystemCallbacks* callbacks) { - FileSystemURL src_url(src_path); - FileSystemURL dest_url(dest_path); + FileSystemURL src_url(file_system_context()->CrackURL(src_path)); + FileSystemURL dest_url(file_system_context()->CrackURL(dest_path)); if (!HasFilePermission(src_url, FILE_PERMISSION_WRITE) || !HasFilePermission(dest_url, FILE_PERMISSION_CREATE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); @@ -137,8 +137,8 @@ void SimpleFileSystem::move( void SimpleFileSystem::copy( const WebURL& src_path, const WebURL& dest_path, WebFileSystemCallbacks* callbacks) { - FileSystemURL src_url(src_path); - FileSystemURL dest_url(dest_path); + FileSystemURL src_url(file_system_context()->CrackURL(src_path)); + FileSystemURL dest_url(file_system_context()->CrackURL(dest_path)); if (!HasFilePermission(src_url, FILE_PERMISSION_READ) || !HasFilePermission(dest_url, FILE_PERMISSION_CREATE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); @@ -150,7 +150,7 @@ void SimpleFileSystem::copy( void SimpleFileSystem::remove( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_WRITE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -161,7 +161,7 @@ void SimpleFileSystem::remove( void SimpleFileSystem::removeRecursively( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_WRITE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -172,7 +172,7 @@ void SimpleFileSystem::removeRecursively( void SimpleFileSystem::readMetadata( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_READ)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -182,7 +182,7 @@ void SimpleFileSystem::readMetadata( void SimpleFileSystem::createFile( const WebURL& path, bool exclusive, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_CREATE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -192,7 +192,7 @@ void SimpleFileSystem::createFile( void SimpleFileSystem::createDirectory( const WebURL& path, bool exclusive, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_CREATE)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -203,7 +203,7 @@ void SimpleFileSystem::createDirectory( void SimpleFileSystem::fileExists( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_READ)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -213,7 +213,7 @@ void SimpleFileSystem::fileExists( void SimpleFileSystem::directoryExists( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_READ)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -223,7 +223,7 @@ void SimpleFileSystem::directoryExists( void SimpleFileSystem::readDirectory( const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_READ)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; @@ -240,7 +240,7 @@ void SimpleFileSystem::createSnapshotFileAndReadMetadata( const WebURL& blobURL, const WebURL& path, WebFileSystemCallbacks* callbacks) { - FileSystemURL url(path); + FileSystemURL url(file_system_context()->CrackURL(path)); if (!HasFilePermission(url, FILE_PERMISSION_READ)) { callbacks->didFail(WebKit::WebFileErrorSecurity); return; diff --git a/webkit/tools/test_shell/simple_file_writer.cc b/webkit/tools/test_shell/simple_file_writer.cc index 4688924..e30e120 100644 --- a/webkit/tools/test_shell/simple_file_writer.cc +++ b/webkit/tools/test_shell/simple_file_writer.cc @@ -182,6 +182,7 @@ SimpleFileWriter::SimpleFileWriter( WebFileWriterClient* client, FileSystemContext* file_system_context) : WebFileWriterBase(path, client), + file_system_context_(file_system_context), io_thread_proxy_(new IOThreadProxy(AsWeakPtr(), file_system_context)) { } @@ -189,13 +190,13 @@ SimpleFileWriter::~SimpleFileWriter() { } void SimpleFileWriter::DoTruncate(const GURL& path, int64 offset) { - FileSystemURL url(path); + FileSystemURL url = file_system_context_->CrackURL(path); io_thread_proxy_->Truncate(url, offset); } void SimpleFileWriter::DoWrite( const GURL& path, const GURL& blob_url, int64 offset) { - FileSystemURL url(path); + FileSystemURL url = file_system_context_->CrackURL(path); io_thread_proxy_->Write(url, blob_url, offset); } diff --git a/webkit/tools/test_shell/simple_file_writer.h b/webkit/tools/test_shell/simple_file_writer.h index f4f3772..8c1a0fd 100644 --- a/webkit/tools/test_shell/simple_file_writer.h +++ b/webkit/tools/test_shell/simple_file_writer.h @@ -45,6 +45,7 @@ class SimpleFileWriter : public fileapi::WebFileWriterBase, private: class IOThreadProxy; + scoped_refptr<fileapi::FileSystemContext> file_system_context_; scoped_refptr<IOThreadProxy> io_thread_proxy_; static net::URLRequestContext* request_context_; }; |