| Index: webkit/fileapi/obfuscated_file_system_file_util.cc
|
| diff --git a/webkit/fileapi/obfuscated_file_system_file_util.cc b/webkit/fileapi/obfuscated_file_system_file_util.cc
|
| index d91f0b47770a71a96189a68983986db00204b647..1e7c16e41cc8e4447d75567ff4e648c47749181d 100644
|
| --- a/webkit/fileapi/obfuscated_file_system_file_util.cc
|
| +++ b/webkit/fileapi/obfuscated_file_system_file_util.cc
|
| @@ -7,9 +7,11 @@
|
| #include <queue>
|
|
|
| #include "base/file_util.h"
|
| +#include "base/format_macros.h"
|
| #include "base/logging.h"
|
| #include "base/message_loop.h"
|
| #include "base/string_number_conversions.h"
|
| +#include "base/stringprintf.h"
|
| #include "base/sys_string_conversions.h"
|
| #include "base/stl_util-inl.h"
|
| #include "googleurl/src/gurl.h"
|
| @@ -32,14 +34,17 @@ const char kDirectoryDatabaseName[] = "Paths";
|
| void InitFileInfo(
|
| fileapi::FileSystemDirectoryDatabase::FileInfo* file_info,
|
| fileapi::FileSystemDirectoryDatabase::FileId parent_id,
|
| - const FilePath::StringType& file_name,
|
| - const FilePath& data_path) {
|
| + const FilePath::StringType& file_name) {
|
| DCHECK(file_info);
|
| file_info->parent_id = parent_id;
|
| - file_info->data_path = data_path;
|
| file_info->name = file_name;
|
| }
|
|
|
| +const FilePath::CharType kLegacyDataDirectory[] = FILE_PATH_LITERAL("Legacy");
|
| +
|
| +const FilePath::CharType kTemporaryDirectoryName[] = FILE_PATH_LITERAL("t");
|
| +const FilePath::CharType kPersistentDirectoryName[] = FILE_PATH_LITERAL("p");
|
| +
|
| } // namespace
|
|
|
| namespace fileapi {
|
| @@ -77,11 +82,10 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen(
|
| if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id))
|
| return base::PLATFORM_FILE_ERROR_NOT_FOUND;
|
| FileInfo file_info;
|
| - InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(),
|
| - FilePath());
|
| + InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value());
|
| PlatformFileError error = CreateFile(
|
| - context, context->src_origin_url(), context->src_type(), &file_info,
|
| - file_flags, file_handle);
|
| + context, context->src_origin_url(), context->src_type(), FilePath(),
|
| + &file_info, file_flags, file_handle);
|
| if (created && base::PLATFORM_FILE_OK == error)
|
| *created = true;
|
| return error;
|
| @@ -96,8 +100,10 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateOrOpen(
|
| }
|
| if (file_info.is_directory())
|
| return base::PLATFORM_FILE_ERROR_NOT_A_FILE;
|
| + FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), file_info.data_path);
|
| return FileSystemFileUtil::GetInstance()->CreateOrOpen(
|
| - context, file_info.data_path, file_flags, file_handle, created);
|
| + context, data_path, file_flags, file_handle, created);
|
| }
|
|
|
| PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists(
|
| @@ -126,10 +132,9 @@ PlatformFileError ObfuscatedFileSystemFileUtil::EnsureFileExists(
|
| return base::PLATFORM_FILE_ERROR_NOT_FOUND;
|
|
|
| FileInfo file_info;
|
| - InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(),
|
| - FilePath());
|
| - PlatformFileError error = CreateFile(context,
|
| - context->src_origin_url(), context->src_type(), &file_info, 0, NULL);
|
| + InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value());
|
| + PlatformFileError error = CreateFile(context, context->src_origin_url(),
|
| + context->src_type(), FilePath(), &file_info, 0, NULL);
|
| if (created && base::PLATFORM_FILE_OK == error)
|
| *created = true;
|
| return error;
|
| @@ -176,8 +181,10 @@ PlatformFileError ObfuscatedFileSystemFileUtil::GetFileInfo(
|
| }
|
| if (local_info.data_path.empty())
|
| return base::PLATFORM_FILE_ERROR_INVALID_OPERATION;
|
| + FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), local_info.data_path);
|
| return FileSystemFileUtil::GetInstance()->GetFileInfo(
|
| - context, local_info.data_path, file_info, platform_file_path);
|
| + context, data_path, file_info, platform_file_path);
|
| }
|
|
|
| PlatformFileError ObfuscatedFileSystemFileUtil::ReadDirectory(
|
| @@ -318,9 +325,13 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile(
|
| * Just update metadata
|
| */
|
| if (copy) {
|
| + FilePath src_data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), src_file_info.data_path);
|
| if (overwrite) {
|
| + FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), dest_file_info.data_path);
|
| return FileSystemFileUtil::GetInstance()->CopyOrMoveFile(context,
|
| - src_file_info.data_path, dest_file_info.data_path, copy);
|
| + src_data_path, dest_data_path, copy);
|
| } else {
|
| FileId dest_parent_id;
|
| if (!db->GetFileWithPath(dest_file_path.DirName(), &dest_parent_id)) {
|
| @@ -328,17 +339,20 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CopyOrMoveFile(
|
| return base::PLATFORM_FILE_ERROR_NOT_FOUND;
|
| }
|
| InitFileInfo(&dest_file_info, dest_parent_id,
|
| - dest_file_path.BaseName().value(), src_file_info.data_path);
|
| + dest_file_path.BaseName().value());
|
| return CreateFile(context, context->dest_origin_url(),
|
| - context->dest_type(), &dest_file_info, 0, NULL);
|
| + context->dest_type(), src_data_path, &dest_file_info, 0,
|
| + NULL);
|
| }
|
| } else { // It's a move.
|
| if (overwrite) {
|
| if (!db->OverwritingMoveFile(src_file_id, dest_file_id))
|
| return base::PLATFORM_FILE_ERROR_FAILED;
|
| + FilePath dest_data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), dest_file_info.data_path);
|
| if (base::PLATFORM_FILE_OK !=
|
| FileSystemFileUtil::GetInstance()->DeleteFile(
|
| - context, dest_file_info.data_path))
|
| + context, dest_data_path))
|
| LOG(WARNING) << "Leaked a backing file.";
|
| return base::PLATFORM_FILE_OK;
|
| } else {
|
| @@ -377,9 +391,10 @@ PlatformFileError ObfuscatedFileSystemFileUtil::DeleteFile(
|
| NOTREACHED();
|
| return base::PLATFORM_FILE_ERROR_FAILED;
|
| }
|
| + FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), file_info.data_path);
|
| if (base::PLATFORM_FILE_OK !=
|
| - FileSystemFileUtil::GetInstance()->DeleteFile(
|
| - context, file_info.data_path))
|
| + FileSystemFileUtil::GetInstance()->DeleteFile(context, data_path))
|
| LOG(WARNING) << "Leaked a backing file.";
|
| return base::PLATFORM_FILE_OK;
|
| }
|
| @@ -426,24 +441,27 @@ PlatformFileError ObfuscatedFileSystemFileUtil::Touch(
|
| return base::PLATFORM_FILE_ERROR_FAILED;
|
| return base::PLATFORM_FILE_OK;
|
| }
|
| + FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), file_info.data_path);
|
| return FileSystemFileUtil::GetInstance()->Touch(
|
| - context, file_info.data_path, last_access_time, last_modified_time);
|
| + context, data_path, last_access_time, last_modified_time);
|
| }
|
| FileId parent_id;
|
| if (!db->GetFileWithPath(virtual_path.DirName(), &parent_id))
|
| return base::PLATFORM_FILE_ERROR_NOT_FOUND;
|
|
|
| FileInfo file_info;
|
| - InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value(),
|
| - FilePath());
|
| + InitFileInfo(&file_info, parent_id, virtual_path.BaseName().value());
|
| // In the event of a sporadic underlying failure, we might create a new file,
|
| // but fail to update its mtime + atime.
|
| - PlatformFileError error = CreateFile(context,
|
| - context->src_origin_url(), context->src_type(), &file_info, 0, NULL);
|
| + PlatformFileError error = CreateFile(context, context->src_origin_url(),
|
| + context->src_type(), FilePath(), &file_info, 0, NULL);
|
| if (base::PLATFORM_FILE_OK != error)
|
| return error;
|
|
|
| - return FileSystemFileUtil::GetInstance()->Touch(context, file_info.data_path,
|
| + FilePath data_path = DataPathToLocalPath(context->src_origin_url(),
|
| + context->src_type(), file_info.data_path);
|
| + return FileSystemFileUtil::GetInstance()->Touch(context, data_path,
|
| last_access_time, last_modified_time);
|
| }
|
|
|
| @@ -598,7 +616,7 @@ ObfuscatedFileSystemFileUtil::CreateFileEnumerator(
|
|
|
| PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile(
|
| FileSystemOperationContext* context,
|
| - const GURL& origin_url, FileSystemType type,
|
| + const GURL& origin_url, FileSystemType type, const FilePath& source_path,
|
| FileInfo* file_info, int file_flags, PlatformFile* handle) {
|
| if (handle)
|
| *handle = base::kInvalidPlatformFileValue;
|
| @@ -612,19 +630,23 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile(
|
| GetDirectoryForOriginAndType(origin_url, type, false);
|
| if (path.empty())
|
| return base::PLATFORM_FILE_ERROR_FAILED;
|
| - path = path.AppendASCII(base::Int64ToString(directory_number));
|
| +
|
| + path = path.AppendASCII(StringPrintf("%02" PRIu64, directory_number));
|
| PlatformFileError error;
|
| error = FileSystemFileUtil::GetInstance()->CreateDirectory(
|
| context, path, false /* exclusive */, false /* recursive */);
|
| if (base::PLATFORM_FILE_OK != error)
|
| return error;
|
| - path = path.AppendASCII(base::Int64ToString(number));
|
| + path = path.AppendASCII(StringPrintf("%08" PRIu64, number));
|
| + FilePath data_path = LocalPathToDataPath(origin_url, type, path);
|
| + if (data_path.empty())
|
| + return base::PLATFORM_FILE_ERROR_FAILED;
|
| bool created = false;
|
| - if (!file_info->data_path.empty()) {
|
| + if (!source_path.empty()) {
|
| DCHECK(!file_flags);
|
| DCHECK(!handle);
|
| error = FileSystemFileUtil::GetInstance()->CopyOrMoveFile(
|
| - context, file_info->data_path, path, true /* copy */);
|
| + context, source_path, path, true /* copy */);
|
| created = true;
|
| } else {
|
| if (handle) {
|
| @@ -648,7 +670,7 @@ PlatformFileError ObfuscatedFileSystemFileUtil::CreateFile(
|
| }
|
| return base::PLATFORM_FILE_ERROR_FAILED;
|
| }
|
| - file_info->data_path = path;
|
| + file_info->data_path = data_path;
|
| FileId file_id;
|
| if (!db->AddFileInfo(*file_info, &file_id)) {
|
| if (handle)
|
| @@ -675,7 +697,7 @@ FilePath ObfuscatedFileSystemFileUtil::GetLocalPath(
|
| NOTREACHED();
|
| return FilePath(); // Directories have no local path.
|
| }
|
| - return file_info.data_path;
|
| + return DataPathToLocalPath(origin_url, type, file_info.data_path);
|
| }
|
|
|
| FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType(
|
| @@ -683,13 +705,12 @@ FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOriginAndType(
|
| FilePath origin_dir = GetDirectoryForOrigin(origin, create);
|
| if (origin_dir.empty())
|
| return FilePath();
|
| - std::string type_string =
|
| - FileSystemPathManager::GetFileSystemTypeString(type);
|
| + FilePath::StringType type_string = GetDirectoryNameForType(type);
|
| if (type_string.empty()) {
|
| LOG(WARNING) << "Unknown filesystem type requested:" << type;
|
| return FilePath();
|
| }
|
| - return origin_dir.AppendASCII(type_string);
|
| + return origin_dir.Append(type_string);
|
| }
|
|
|
| FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin(
|
| @@ -717,6 +738,99 @@ FilePath ObfuscatedFileSystemFileUtil::GetDirectoryForOrigin(
|
| return file_system_directory_.Append(directory_name);
|
| }
|
|
|
| +bool ObfuscatedFileSystemFileUtil::MigrateFromOldSandbox(
|
| + const GURL& origin_url, FileSystemType type, const FilePath& src_root) {
|
| + if (!DestroyDirectoryDatabase(origin_url, type))
|
| + return false;
|
| + FilePath dest_root = GetDirectoryForOriginAndType(origin_url, type, true);
|
| + if (dest_root.empty())
|
| + return false;
|
| + FileSystemDirectoryDatabase* db = GetDirectoryDatabase(origin_url, type);
|
| + if (!db)
|
| + return false;
|
| +
|
| + file_util::FileEnumerator file_enum(src_root, true,
|
| + static_cast<file_util::FileEnumerator::FILE_TYPE>(
|
| + file_util::FileEnumerator::FILES |
|
| + file_util::FileEnumerator::DIRECTORIES));
|
| + FilePath src_full_path;
|
| + size_t root_path_length = src_root.value().length() + 1; // +1 for the slash
|
| + while (!(src_full_path = file_enum.Next()).empty()) {
|
| + file_util::FileEnumerator::FindInfo info;
|
| + file_enum.GetFindInfo(&info);
|
| + FilePath relative_virtual_path =
|
| + FilePath(src_full_path.value().substr(root_path_length));
|
| + if (relative_virtual_path.empty()) {
|
| + LOG(WARNING) << "Failed to convert path to relative: " <<
|
| + src_full_path.value();
|
| + return false;
|
| + }
|
| + FileId file_id;
|
| + if (db->GetFileWithPath(relative_virtual_path, &file_id)) {
|
| + NOTREACHED(); // File already exists.
|
| + return false;
|
| + }
|
| + if (!db->GetFileWithPath(relative_virtual_path.DirName(), &file_id)) {
|
| + NOTREACHED(); // Parent doesn't exist.
|
| + return false;
|
| + }
|
| +
|
| + FileInfo file_info;
|
| + file_info.name = src_full_path.BaseName().value();
|
| + if (file_util::FileEnumerator::IsDirectory(info)) {
|
| +#if defined(OS_WIN)
|
| + file_info.modification_time =
|
| + base::Time::FromFileTime(info.ftLastWriteTime);
|
| +#elif defined(OS_POSIX)
|
| + file_info.modification_time = base::Time::FromTimeT(info.stat.st_mtime);
|
| +#endif
|
| + } else {
|
| + file_info.data_path =
|
| + FilePath(kLegacyDataDirectory).Append(relative_virtual_path);
|
| + }
|
| + file_info.parent_id = file_id;
|
| + if (!db->AddFileInfo(file_info, &file_id)) {
|
| + NOTREACHED();
|
| + return false;
|
| + }
|
| + }
|
| + // TODO(ericu): Should we adjust the mtime of the root directory to match as
|
| + // well?
|
| + FilePath legacy_dest_dir = dest_root.Append(kLegacyDataDirectory);
|
| + return file_util::Move(src_root, legacy_dest_dir);
|
| +}
|
| +
|
| +FilePath::StringType ObfuscatedFileSystemFileUtil::GetDirectoryNameForType(
|
| + FileSystemType type) const {
|
| + switch (type) {
|
| + case kFileSystemTypeTemporary:
|
| + return kTemporaryDirectoryName;
|
| + case kFileSystemTypePersistent:
|
| + return kPersistentDirectoryName;
|
| + case kFileSystemTypeUnknown:
|
| + default:
|
| + return FilePath::StringType();
|
| + }
|
| +}
|
| +
|
| +FilePath ObfuscatedFileSystemFileUtil::DataPathToLocalPath(
|
| + const GURL& origin, FileSystemType type, const FilePath& data_path) {
|
| + FilePath root = GetDirectoryForOriginAndType(origin, type, false);
|
| + if (root.empty())
|
| + return root;
|
| + return root.Append(data_path);
|
| +}
|
| +
|
| +FilePath ObfuscatedFileSystemFileUtil::LocalPathToDataPath(
|
| + const GURL& origin, FileSystemType type, const FilePath& local_path) {
|
| + FilePath root = GetDirectoryForOriginAndType(origin, type, false);
|
| + if (root.empty())
|
| + return root;
|
| + // This removes the root, including the trailing slash, leaving a relative
|
| + // path.
|
| + return FilePath(local_path.value().substr(root.value().length() + 1));
|
| +}
|
| +
|
| // TODO: How to do the whole validation-without-creation thing? We may not have
|
| // quota even to create the database. Ah, in that case don't even get here?
|
| // Still doesn't answer the quota issue, though.
|
| @@ -767,4 +881,28 @@ void ObfuscatedFileSystemFileUtil::DropDatabases() {
|
| directories_.clear();
|
| }
|
|
|
| +bool ObfuscatedFileSystemFileUtil::DestroyDirectoryDatabase(
|
| + const GURL& origin, FileSystemType type) {
|
| + std::string type_string =
|
| + FileSystemPathManager::GetFileSystemTypeString(type);
|
| + if (type_string.empty()) {
|
| + LOG(WARNING) << "Unknown filesystem type requested:" << type;
|
| + return true;
|
| + }
|
| + // TODO(ericu): This should probably be using GetOriginIdentifierFromURL from
|
| + // sandbox_mount_point_provider.cc, instead of just using origin.spec().
|
| + std::string key = origin.spec() + type_string;
|
| + DirectoryMap::iterator iter = directories_.find(key);
|
| + if (iter != directories_.end())
|
| + directories_.erase(iter);
|
| +
|
| + FilePath path = GetDirectoryForOriginAndType(origin, type, false);
|
| + if (path.empty())
|
| + return true;
|
| + if (!file_util::DirectoryExists(path))
|
| + return true;
|
| + path = path.AppendASCII(kDirectoryDatabaseName);
|
| + return FileSystemDirectoryDatabase::DestroyDatabase(path);
|
| +}
|
| +
|
| } // namespace fileapi
|
|
|