#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/strings/string_number_conversions.h"
+#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/sys_string_conversions.h"
#include "base/strings/utf_string_conversions.h"
const int64 kPathCreationQuotaCost = 146; // Bytes per inode, basically.
const int64 kPathByteQuotaCost = 2; // Bytes per byte of path length in UTF-8.
+const char kDirectoryDatabaseKeySeparator = ' ';
+
int64 UsageForPath(size_t length) {
return kPathCreationQuotaCost +
static_cast<int64>(length) * kPathByteQuotaCost;
recurse_queue_.push(record);
}
- virtual ~ObfuscatedFileEnumerator() {}
+ ~ObfuscatedFileEnumerator() override {}
- virtual base::FilePath Next() OVERRIDE {
+ base::FilePath Next() override {
ProcessRecurseQueue();
if (display_stack_.empty())
return base::FilePath();
return virtual_path;
}
- virtual int64 Size() OVERRIDE {
- return current_platform_file_info_.size;
- }
+ int64 Size() override { return current_platform_file_info_.size; }
- virtual base::Time LastModifiedTime() OVERRIDE {
+ base::Time LastModifiedTime() override {
return current_platform_file_info_.last_modified;
}
- virtual bool IsDirectory() OVERRIDE {
+ bool IsDirectory() override {
return current_platform_file_info_.is_directory;
}
origin_database->ListAllOrigins(&origins_);
}
- virtual ~ObfuscatedOriginEnumerator() {}
+ ~ObfuscatedOriginEnumerator() override {}
// Returns the next origin. Returns empty if there are no more origins.
- virtual GURL Next() OVERRIDE {
+ GURL Next() override {
OriginRecord record;
if (!origins_.empty()) {
record = origins_.back();
}
// Returns the current origin's information.
- virtual bool HasTypeDirectory(const std::string& type_string) const OVERRIDE {
+ bool HasTypeDirectory(const std::string& type_string) const override {
if (current_.path.empty())
return false;
if (type_string.empty()) {
bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
const GURL& origin,
const std::string& type_string) {
- base::File::Error error = base::File::FILE_OK;
- base::FilePath origin_type_path = GetDirectoryForOriginAndType(
- origin, type_string, false, &error);
- if (origin_type_path.empty())
- return true;
- if (error != base::File::FILE_ERROR_NOT_FOUND) {
- // TODO(dmikurube): Consider the return value of DestroyDirectoryDatabase.
- // We ignore its error now since 1) it doesn't matter the final result, and
- // 2) it always returns false in Windows because of LevelDB's
- // implementation.
- // Information about failure would be useful for debugging.
- if (!type_string.empty())
- DestroyDirectoryDatabase(origin, type_string);
- if (!base::DeleteFile(origin_type_path, true /* recursive */))
- return false;
- }
-
- base::FilePath origin_path = VirtualPath::DirName(origin_type_path);
- DCHECK_EQ(origin_path.value(),
- GetDirectoryForOrigin(origin, false, NULL).value());
+ DestroyDirectoryDatabase(origin, type_string);
+ const base::FilePath origin_path = GetDirectoryForOrigin(origin, false, NULL);
if (!type_string.empty()) {
+ // Delete the filesystem type directory.
+ base::File::Error error = base::File::FILE_OK;
+ const base::FilePath origin_type_path =
+ GetDirectoryForOriginAndType(origin, type_string, false, &error);
+ if (error == base::File::FILE_ERROR_FAILED)
+ return false;
+ if (error == base::File::FILE_OK &&
+ !origin_type_path.empty() &&
+ !base::DeleteFile(origin_type_path, true /* recursive */)) {
+ return false;
+ }
+
// At this point we are sure we had successfully deleted the origin/type
// directory (i.e. we're ready to just return true).
// See if we have other directories in this origin directory.
origin_database_->RemovePathForOrigin(
storage::GetIdentifierFromOrigin(origin));
}
- if (!base::DeleteFile(origin_path, true /* recursive */))
- return false;
-
- return true;
+ return base::DeleteFile(origin_path, true /* recursive */);
}
ObfuscatedFileUtil::AbstractOriginEnumerator*
origin_database_.get(), file_system_directory_);
}
-bool ObfuscatedFileUtil::DestroyDirectoryDatabase(
+void ObfuscatedFileUtil::DestroyDirectoryDatabase(
const GURL& origin,
const std::string& type_string) {
- std::string key = GetDirectoryDatabaseKey(origin, type_string);
- if (key.empty())
- return true;
- DirectoryMap::iterator iter = directories_.find(key);
- if (iter == directories_.end())
- return true;
- scoped_ptr<SandboxDirectoryDatabase> database(iter->second);
- directories_.erase(iter);
- return database->DestroyDatabase();
+ // If |type_string| is empty, delete all filesystem types under |origin|.
+ const std::string key_prefix = GetDirectoryDatabaseKey(origin, type_string);
+ for (DirectoryMap::iterator iter = directories_.lower_bound(key_prefix);
+ iter != directories_.end();) {
+ if (!StartsWithASCII(iter->first, key_prefix, true))
+ break;
+ DCHECK(type_string.empty() || iter->first == key_prefix);
+ scoped_ptr<SandboxDirectoryDatabase> database(iter->second);
+ directories_.erase(iter++);
+
+ // Continue to destroy databases even if it failed because it doesn't affect
+ // the final result.
+ database->DestroyDatabase();
+ }
}
// static
std::string ObfuscatedFileUtil::GetDirectoryDatabaseKey(
const GURL& origin, const std::string& type_string) {
- if (type_string.empty()) {
- LOG(WARNING) << "Unknown filesystem type requested:" << type_string;
- return std::string();
- }
// For isolated origin we just use a type string as a key.
- return storage::GetIdentifierFromOrigin(origin) + type_string;
+ return storage::GetIdentifierFromOrigin(origin) +
+ kDirectoryDatabaseKeySeparator + type_string;
}
// TODO(ericu): How to do the whole validation-without-creation thing?