Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Unified Diff: webkit/fileapi/file_system_path_manager.cc

Issue 6603034: Stop returning the true root path of each filesystem from openFileSystem.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 9 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « webkit/fileapi/file_system_path_manager.h ('k') | webkit/fileapi/file_system_path_manager_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: webkit/fileapi/file_system_path_manager.cc
===================================================================
--- webkit/fileapi/file_system_path_manager.cc (revision 79142)
+++ webkit/fileapi/file_system_path_manager.cc (working copy)
@@ -1,4 +1,4 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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.
@@ -14,171 +14,33 @@
#include "base/string_util.h"
#include "base/utf_string_conversions.h"
#include "googleurl/src/gurl.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFileSystem.h"
-#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "webkit/fileapi/file_system_util.h"
+#include "webkit/fileapi/sandbox_mount_point_provider.h"
#include "webkit/glue/webkit_glue.h"
// We use some of WebKit types for conversions between origin identifiers
// and origin URLs.
using WebKit::WebFileSystem;
-using WebKit::WebSecurityOrigin;
-using WebKit::WebString;
using base::PlatformFileError;
-namespace fileapi {
-
-const FilePath::CharType FileSystemPathManager::kFileSystemDirectory[] =
- FILE_PATH_LITERAL("FileSystem");
-
-const char FileSystemPathManager::kPersistentName[] = "Persistent";
-const char FileSystemPathManager::kTemporaryName[] = "Temporary";
-
-static const FilePath::CharType kFileSystemUniqueNamePrefix[] =
- FILE_PATH_LITERAL("chrome-");
-static const int kFileSystemUniqueLength = 16;
-static const unsigned kFileSystemUniqueDirectoryNameLength =
- kFileSystemUniqueLength + arraysize(kFileSystemUniqueNamePrefix) - 1;
-
-namespace {
-
-// Restricted names.
-// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
-static const char* const kRestrictedNames[] = {
- "con", "prn", "aux", "nul",
- "com1", "com2", "com3", "com4", "com5", "com6", "com7", "com8", "com9",
- "lpt1", "lpt2", "lpt3", "lpt4", "lpt5", "lpt6", "lpt7", "lpt8", "lpt9",
-};
-
-// Restricted chars.
-static const FilePath::CharType kRestrictedChars[] = {
- '/', '\\', '<', '>', ':', '?', '*', '"', '|',
-};
-
-inline std::string FilePathStringToASCII(
- const FilePath::StringType& path_string) {
-#if defined(OS_WIN)
- return WideToASCII(path_string);
-#elif defined(OS_POSIX)
- return path_string;
-#endif
-}
-
-FilePath::StringType CreateUniqueDirectoryName(const GURL& origin_url) {
- // This can be anything but need to be unpredictable.
- static const FilePath::CharType letters[] = FILE_PATH_LITERAL(
- "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
- FilePath::StringType unique(kFileSystemUniqueNamePrefix);
- for (int i = 0; i < kFileSystemUniqueLength; ++i)
- unique += letters[base::RandInt(0, arraysize(letters) - 2)];
- return unique;
-}
-
static const char kExtensionScheme[] = "chrome-extension";
-} // anonymous namespace
+namespace fileapi {
-class FileSystemPathManager::GetFileSystemRootPathTask
- : public base::RefCountedThreadSafe<
- FileSystemPathManager::GetFileSystemRootPathTask> {
- public:
- GetFileSystemRootPathTask(
- scoped_refptr<base::MessageLoopProxy> file_message_loop,
- const std::string& name,
- FileSystemPathManager::GetRootPathCallback* callback)
- : file_message_loop_(file_message_loop),
- origin_message_loop_proxy_(
- base::MessageLoopProxy::CreateForCurrentThread()),
- name_(name),
- callback_(callback) {
- }
-
- void Start(const GURL& origin_url,
- const FilePath& origin_base_path,
- bool create) {
- file_message_loop_->PostTask(FROM_HERE, NewRunnableMethod(this,
- &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread,
- origin_url, origin_base_path, create));
- }
-
- private:
- void GetFileSystemRootPathOnFileThread(
- const GURL& origin_url,
- const FilePath& base_path,
- bool create) {
- FilePath root;
- if (ReadOriginDirectory(base_path, origin_url, &root)) {
- DispatchCallbackOnCallerThread(root);
- return;
- }
-
- if (!create) {
- DispatchCallbackOnCallerThread(FilePath());
- return;
- }
-
- // Creates the root directory.
- root = base_path.Append(CreateUniqueDirectoryName(origin_url));
- if (!file_util::CreateDirectory(root)) {
- DispatchCallbackOnCallerThread(FilePath());
- return;
- }
- DispatchCallbackOnCallerThread(root);
- }
-
- bool ReadOriginDirectory(const FilePath& base_path,
- const GURL& origin_url,
- FilePath* unique) {
- file_util::FileEnumerator file_enum(
- base_path, false /* recursive */,
- file_util::FileEnumerator::DIRECTORIES,
- FilePath::StringType(kFileSystemUniqueNamePrefix) +
- FILE_PATH_LITERAL("*"));
- FilePath current;
- bool found = false;
- while (!(current = file_enum.Next()).empty()) {
- if (current.BaseName().value().length() !=
- kFileSystemUniqueDirectoryNameLength)
- continue;
- if (found) {
- // TODO(kinuko): Should notify the user to ask for some action.
- LOG(WARNING) << "Unexpectedly found more than one FileSystem "
- << "directories for " << origin_url;
- return false;
- }
- found = true;
- *unique = current;
- }
- return !unique->empty();
- }
-
- void DispatchCallbackOnCallerThread(const FilePath& root_path) {
- origin_message_loop_proxy_->PostTask(FROM_HERE,
- NewRunnableMethod(this, &GetFileSystemRootPathTask::DispatchCallback,
- root_path));
- }
-
- void DispatchCallback(const FilePath& root_path) {
- callback_->Run(!root_path.empty(), root_path, name_);
- callback_.reset();
- }
-
- scoped_refptr<base::MessageLoopProxy> file_message_loop_;
- scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
- std::string name_;
- scoped_ptr<FileSystemPathManager::GetRootPathCallback> callback_;
-};
-
FileSystemPathManager::FileSystemPathManager(
scoped_refptr<base::MessageLoopProxy> file_message_loop,
const FilePath& profile_path,
bool is_incognito,
bool allow_file_access_from_files)
- : file_message_loop_(file_message_loop),
- base_path_(profile_path.Append(kFileSystemDirectory)),
- is_incognito_(is_incognito),
- allow_file_access_from_files_(allow_file_access_from_files) {
+ : is_incognito_(is_incognito),
+ allow_file_access_from_files_(allow_file_access_from_files),
+ sandbox_provider_(
+ new SandboxMountPointProvider(
+ ALLOW_THIS_IN_INITIALIZER_LIST(this),
+ file_message_loop,
+ profile_path)) {
}
FileSystemPathManager::~FileSystemPathManager() {}
@@ -186,95 +48,88 @@
void FileSystemPathManager::GetFileSystemRootPath(
const GURL& origin_url, fileapi::FileSystemType type,
bool create, GetRootPathCallback* callback_ptr) {
- scoped_ptr<GetRootPathCallback> callback(callback_ptr);
- if (is_incognito_) {
- // TODO(kinuko): return an isolated temporary directory.
- callback->Run(false, FilePath(), std::string());
- return;
- }
- if (!IsAllowedScheme(origin_url)) {
- callback->Run(false, FilePath(), std::string());
- return;
+ switch (type) {
+ case kFileSystemTypeTemporary:
+ case kFileSystemTypePersistent:
+ sandbox_provider_->GetFileSystemRootPath(
+ origin_url, type, create, callback_ptr);
+ break;
+ case kFileSystemTypeUnknown:
+ default:
+ NOTREACHED();
+ callback_ptr->Run(false, FilePath(), std::string());
}
+}
- std::string origin_identifier = GetOriginIdentifierFromURL(origin_url);
- FilePath origin_base_path = GetFileSystemBaseDirectoryForOriginAndType(
- base_path(), origin_identifier, type);
- if (origin_base_path.empty()) {
- callback->Run(false, FilePath(), std::string());
- return;
+FilePath FileSystemPathManager::GetFileSystemRootPathOnFileThread(
+ const GURL& origin_url, FileSystemType type, bool create) {
+ switch (type) {
+ case kFileSystemTypeTemporary:
+ case kFileSystemTypePersistent:
+ return sandbox_provider_->GetFileSystemRootPathOnFileThread(
+ origin_url, type, create);
+ break;
+ case kFileSystemTypeUnknown:
+ default:
+ NOTREACHED();
+ return FilePath();
}
-
- std::string type_string = GetFileSystemTypeString(type);
- DCHECK(!type_string.empty());
-
- scoped_refptr<GetFileSystemRootPathTask> task(
- new GetFileSystemRootPathTask(file_message_loop_,
- origin_identifier + ":" + type_string,
- callback.release()));
- task->Start(origin_url, origin_base_path, create);
}
bool FileSystemPathManager::CrackFileSystemPath(
const FilePath& path, GURL* origin_url, FileSystemType* type,
FilePath* virtual_path) const {
- // Any paths that includes parent references are considered invalid.
- if (path.ReferencesParent())
- return false;
+ // TODO(ericu):
+ // Paths come in here [for now] as a URL, followed by a virtual path in
+ // platform format. For example, on Windows, this will look like
+ // filesystem:http://www.example.com/temporary/\path\to\file.txt.
+ // A potentially dangerous malicious path on Windows might look like:
+ // filesystem:http://www.example.com/temporary/foo/../../\path\to\file.txt.
+ // This code is ugly, but will get cleaned up as we fix the calling side.
+ // Eventually there won't be a distinction between a filesystem path and a
+ // filesystem URL--they'll all be URLs.
+ // We should be passing these to WebKit as string, not FilePath, for ease of
+ // manipulation, or possibly as GURL/KURL.
- // The path should be a child of the profile FileSystem path.
- FilePath relative;
- if (!base_path_.AppendRelativePath(path, &relative))
- return false;
+ std::string path_as_string;
+#ifdef OS_WIN
+ path_as_string = WideToUTF8(path.value());
+#else
+ path_as_string = path.value();
+#endif
+ GURL path_as_url(path_as_string);
- // The relative path from the profile FileSystem path should contain
- // at least three components, one for storage identifier, one for type
- // and one for the 'unique' part.
- std::vector<FilePath::StringType> components;
- relative.GetComponents(&components);
- if (components.size() < 3)
+ FilePath local_path;
+ GURL local_url;
+ FileSystemType local_type;
+ if (!CrackFileSystemURL(path_as_url, &local_url, &local_type, &local_path))
return false;
- // The second component of the relative path to the root directory
- // must be kPersistent or kTemporary.
- if (!IsStringASCII(components[1]))
- return false;
+#if defined(FILE_PATH_USES_WIN_SEPARATORS)
+ // TODO(ericu): This puts the separators back to windows-standard; they come
+ // out of the above code as '/' no matter the platform. Long-term, we'll
+ // want to let the underlying FileSystemFileUtil implementation do this part,
+ // since they won't all need it.
+ local_path = local_path.NormalizeWindowsPathSeparators();
+#endif
- std::string ascii_type_component = FilePathStringToASCII(components[1]);
- FileSystemType cracked_type = kFileSystemTypeUnknown;
- if (ascii_type_component == kPersistentName)
- cracked_type = kFileSystemTypePersistent;
- else if (ascii_type_component == kTemporaryName)
- cracked_type = kFileSystemTypeTemporary;
- else
- return false;
+ // Any paths that include parent references are considered invalid.
+ // These should have been taken care of in CrackFileSystemURL.
+ DCHECK(!local_path.ReferencesParent());
- DCHECK(cracked_type != kFileSystemTypeUnknown);
-
- // The given |path| seems valid. Populates the |origin_url|, |type|
+ // The given |local_path| seems valid. Populates the |origin_url|, |type|
// and |virtual_path| if they are given.
if (origin_url) {
- WebSecurityOrigin web_security_origin =
- WebSecurityOrigin::createFromDatabaseIdentifier(
- webkit_glue::FilePathStringToWebString(components[0]));
- *origin_url = GURL(web_security_origin.toString());
-
- // We need this work-around for file:/// URIs as
- // createFromDatabaseIdentifier returns empty origin_url for them.
- if (allow_file_access_from_files_ && origin_url->spec().empty() &&
- components[0].find(FILE_PATH_LITERAL("file")) == 0)
- *origin_url = GURL("file:///");
+ *origin_url = local_url;
}
if (type)
- *type = cracked_type;
+ *type = local_type;
if (virtual_path) {
- virtual_path->clear();
- for (size_t i = 3; i < components.size(); ++i)
- *virtual_path = virtual_path->Append(components[i]);
+ *virtual_path = local_path;
}
return true;
@@ -289,89 +144,29 @@
}
// static
-bool FileSystemPathManager::IsRestrictedFileName(const FilePath& filename) {
- if (filename.value().empty())
- return false;
-
- if (IsWhitespace(filename.value()[filename.value().size() - 1]) ||
- filename.value()[filename.value().size() - 1] == '.')
- return true;
-
- std::string filename_lower = StringToLowerASCII(
- FilePathStringToASCII(filename.value()));
-
- for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
- // Exact match.
- if (filename_lower == kRestrictedNames[i])
- return true;
- // Starts with "RESTRICTED_NAME.".
- if (filename_lower.find(std::string(kRestrictedNames[i]) + ".") == 0)
- return true;
- }
-
- for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
- if (filename.value().find(kRestrictedChars[i]) !=
- FilePath::StringType::npos)
- return true;
- }
-
- return false;
-}
-
-// static
std::string FileSystemPathManager::GetFileSystemTypeString(
fileapi::FileSystemType type) {
if (type == fileapi::kFileSystemTypeTemporary)
- return fileapi::FileSystemPathManager::kTemporaryName;
+ return fileapi::SandboxMountPointProvider::kTemporaryName;
else if (type == fileapi::kFileSystemTypePersistent)
- return fileapi::FileSystemPathManager::kPersistentName;
+ return fileapi::SandboxMountPointProvider::kPersistentName;
return std::string();
}
-// static
-std::string FileSystemPathManager::GetOriginIdentifierFromURL(
- const GURL& url) {
- WebKit::WebSecurityOrigin web_security_origin =
- WebKit::WebSecurityOrigin::createFromString(UTF8ToUTF16(url.spec()));
- return web_security_origin.databaseIdentifier().utf8();
-}
-
-// static
-FilePath FileSystemPathManager::GetFileSystemBaseDirectoryForOriginAndType(
- const FilePath& base_path, const std::string& origin_identifier,
- fileapi::FileSystemType type) {
- if (origin_identifier.empty())
- return FilePath();
- std::string type_string = GetFileSystemTypeString(type);
- if (type_string.empty()) {
- LOG(WARNING) << "Unknown filesystem type is requested:" << type;
- return FilePath();
+// Checks if a given |name| contains any restricted names/chars in it.
+bool FileSystemPathManager::IsRestrictedFileName(
+ FileSystemType type, const FilePath& filename) {
+ switch (type) {
+ case kFileSystemTypeTemporary:
+ case kFileSystemTypePersistent:
+ return sandbox_provider_->IsRestrictedFileName(filename);
+ case kFileSystemTypeUnknown:
+ default:
+ NOTREACHED();
+ return true;
}
- return base_path.AppendASCII(origin_identifier)
- .AppendASCII(type_string);
}
-FileSystemPathManager::OriginEnumerator::OriginEnumerator(
- const FilePath& base_path)
- : enumerator_(base_path, false /* recursive */,
- file_util::FileEnumerator::DIRECTORIES) {
-}
-
-std::string FileSystemPathManager::OriginEnumerator::Next() {
- current_ = enumerator_.Next();
- return FilePathStringToASCII(current_.BaseName().value());
-}
-
-bool FileSystemPathManager::OriginEnumerator::HasTemporary() {
- return !current_.empty() && file_util::DirectoryExists(current_.AppendASCII(
- FileSystemPathManager::kTemporaryName));
-}
-
-bool FileSystemPathManager::OriginEnumerator::HasPersistent() {
- return !current_.empty() && file_util::DirectoryExists(current_.AppendASCII(
- FileSystemPathManager::kPersistentName));
-}
-
} // namespace fileapi
COMPILE_ASSERT(int(WebFileSystem::TypeTemporary) == \
« no previous file with comments | « webkit/fileapi/file_system_path_manager.h ('k') | webkit/fileapi/file_system_path_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698