summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extensions_service.cc12
-rw-r--r--chrome/browser/extensions/extensions_service_unittest.cc9
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.cc34
-rw-r--r--chrome/browser/file_system/file_system_dispatcher_host.h11
-rw-r--r--chrome/browser/file_system/file_system_host_context.cc119
-rw-r--r--chrome/browser/file_system/file_system_host_context.h29
-rw-r--r--chrome/browser/file_system/file_system_host_context_unittest.cc3
-rw-r--r--webkit/fileapi/file_system_quota.cc35
-rw-r--r--webkit/fileapi/file_system_quota.h42
-rw-r--r--webkit/fileapi/file_system_quota_unittest.cc146
-rw-r--r--webkit/fileapi/webkit_fileapi.gypi2
-rw-r--r--webkit/glue/webkit_glue.cc4
-rw-r--r--webkit/tools/test_shell/test_shell.gypi1
13 files changed, 434 insertions, 13 deletions
diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc
index 286a283..457be14 100644
--- a/chrome/browser/extensions/extensions_service.cc
+++ b/chrome/browser/extensions/extensions_service.cc
@@ -1168,6 +1168,12 @@ void ExtensionsService::GrantUnlimitedStorage(Extension* extension) {
&ChromeAppCacheService::SetOriginQuotaInMemory,
origin,
kint64max));
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ profile_->GetFileSystemHostContext(),
+ &FileSystemHostContext::SetOriginQuotaUnlimited,
+ origin));
}
}
}
@@ -1197,6 +1203,12 @@ void ExtensionsService::RevokeUnlimitedStorage(Extension* extension) {
profile_->GetAppCacheService(),
&ChromeAppCacheService::ResetOriginQuotaInMemory,
origin));
+ ChromeThread::PostTask(
+ ChromeThread::IO, FROM_HERE,
+ NewRunnableMethod(
+ profile_->GetFileSystemHostContext(),
+ &FileSystemHostContext::ResetOriginQuotaUnlimited,
+ origin));
}
}
}
diff --git a/chrome/browser/extensions/extensions_service_unittest.cc b/chrome/browser/extensions/extensions_service_unittest.cc
index 7d6733d..7a1c384 100644
--- a/chrome/browser/extensions/extensions_service_unittest.cc
+++ b/chrome/browser/extensions/extensions_service_unittest.cc
@@ -23,6 +23,7 @@
#include "base/version.h"
#include "chrome/browser/appcache/chrome_appcache_service.h"
#include "chrome/browser/chrome_thread.h"
+#include "chrome/browser/file_system/file_system_host_context.h"
#include "chrome/browser/extensions/crx_installer.h"
#include "chrome/browser/extensions/extension_creator.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
@@ -257,9 +258,17 @@ class ExtensionTestingProfile : public TestingProfile {
return appcache_service_;
}
+ virtual FileSystemHostContext* GetFileSystemHostContext() {
+ if (!file_system_host_context_)
+ file_system_host_context_ = new FileSystemHostContext(
+ GetPath(), IsOffTheRecord());
+ return file_system_host_context_;
+ }
+
private:
ExtensionsService* service_;
scoped_refptr<ChromeAppCacheService> appcache_service_;
+ scoped_refptr<FileSystemHostContext> file_system_host_context_;
};
// Our message loop may be used in tests which require it to be an IO loop.
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.cc b/chrome/browser/file_system/file_system_dispatcher_host.cc
index b2e9cb6..28ffe03 100644
--- a/chrome/browser/file_system/file_system_dispatcher_host.cc
+++ b/chrome/browser/file_system/file_system_dispatcher_host.cc
@@ -18,6 +18,9 @@
#include "chrome/common/render_messages_params.h"
#include "googleurl/src/gurl.h"
#include "net/url_request/url_request_context.h"
+#include "webkit/fileapi/file_system_quota.h"
+
+using fileapi::FileSystemQuota;
// A class to hold an ongoing openFileSystem completion task.
struct OpenFileSystemCompletionTask {
@@ -157,7 +160,8 @@ void FileSystemDispatcherHost::OnOpenFileSystem(
void FileSystemDispatcherHost::OnMove(
int request_id, const FilePath& src_path, const FilePath& dest_path) {
if (!CheckValidFileSystemPath(src_path, request_id) ||
- !CheckValidFileSystemPath(dest_path, request_id))
+ !CheckValidFileSystemPath(dest_path, request_id) ||
+ !CheckQuotaForPath(dest_path, FileSystemQuota::kUnknownSize, request_id))
return;
GetNewOperation(request_id)->Move(src_path, dest_path);
@@ -166,7 +170,8 @@ void FileSystemDispatcherHost::OnMove(
void FileSystemDispatcherHost::OnCopy(
int request_id, const FilePath& src_path, const FilePath& dest_path) {
if (!CheckValidFileSystemPath(src_path, request_id) ||
- !CheckValidFileSystemPath(dest_path, request_id))
+ !CheckValidFileSystemPath(dest_path, request_id) ||
+ !CheckQuotaForPath(dest_path, FileSystemQuota::kUnknownSize, request_id))
return;
GetNewOperation(request_id)->Copy(src_path, dest_path);
@@ -189,7 +194,8 @@ void FileSystemDispatcherHost::OnReadMetadata(
void FileSystemDispatcherHost::OnCreate(
int request_id, const FilePath& path, bool exclusive,
bool is_directory, bool recursive) {
- if (!CheckValidFileSystemPath(path, request_id))
+ if (!CheckValidFileSystemPath(path, request_id) ||
+ !CheckQuotaForPath(path, 0L, request_id))
return;
if (is_directory)
GetNewOperation(request_id)->CreateDirectory(path, exclusive, recursive);
@@ -219,7 +225,8 @@ void FileSystemDispatcherHost::OnWrite(
const FilePath& path,
const GURL& blob_url,
int64 offset) {
- if (!CheckValidFileSystemPath(path, request_id))
+ if (!CheckValidFileSystemPath(path, request_id) ||
+ !CheckQuotaForPath(path, FileSystemQuota::kUnknownSize, request_id))
return;
GetNewOperation(request_id)->Write(
request_context_, path, blob_url, offset);
@@ -281,6 +288,25 @@ bool FileSystemDispatcherHost::CheckValidFileSystemPath(
return true;
}
+bool FileSystemDispatcherHost::CheckQuotaForPath(
+ const FilePath& path, int64 growth, int request_id) {
+ GURL origin_url;
+ if (!context_->GetOriginFromPath(path, &origin_url)) {
+ // Appears to be an ill-formed path or for an unallowed scheme.
+ Send(new ViewMsg_FileSystem_DidFail(
+ request_id, base::PLATFORM_FILE_ERROR_SECURITY));
+ return false;
+ }
+ // TODO(kinuko): For operations with kUnknownSize we'll eventually
+ // need to resolve what amount of size it's going to write.
+ if (!context_->CheckOriginQuota(origin_url, growth)) {
+ Send(new ViewMsg_FileSystem_DidFail(
+ request_id, base::PLATFORM_FILE_ERROR_NO_SPACE));
+ return false;
+ }
+ return true;
+}
+
fileapi::FileSystemOperation* FileSystemDispatcherHost::GetNewOperation(
int request_id) {
BrowserFileSystemCallbackDispatcher* dispatcher =
diff --git a/chrome/browser/file_system/file_system_dispatcher_host.h b/chrome/browser/file_system/file_system_dispatcher_host.h
index 201ade6..33e6011 100644
--- a/chrome/browser/file_system/file_system_dispatcher_host.h
+++ b/chrome/browser/file_system/file_system_dispatcher_host.h
@@ -80,10 +80,17 @@ class FileSystemDispatcherHost
fileapi::FileSystemOperation* GetNewOperation(int request_id);
// Checks the validity of a given |path|. Returns true if the given |path|
- // is valid as a path for FileSystem API. Otherwise it sends back a
- // security error code to the dispatcher and returns false.
+ // is valid as a path for FileSystem API. Otherwise it sends back
+ // PLATFORM_FILE_ERROR_SECURITY to the dispatcher and returns false.
bool CheckValidFileSystemPath(const FilePath& path, int request_id);
+ // Checks the quota for the given |path|. This method only performs a
+ // in-memory quick check and returns immediately.
+ // Returns true if the given |path| will be able to grow by |growth|.
+ // Otherwise it sends back PLATFORM_FILE_ERROR_NO_SPACE to the dispatcher
+ // and returns false.
+ bool CheckQuotaForPath(const FilePath& path, int64 growth, int request_id);
+
// The sender to be used for sending out IPC messages.
IPC::Message::Sender* message_sender_;
diff --git a/chrome/browser/file_system/file_system_host_context.cc b/chrome/browser/file_system/file_system_host_context.cc
index f0cea3b..e7b1f5c 100644
--- a/chrome/browser/file_system/file_system_host_context.cc
+++ b/chrome/browser/file_system/file_system_host_context.cc
@@ -4,13 +4,23 @@
#include "chrome/browser/file_system/file_system_host_context.h"
+#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
+#include "base/string_util.h"
#include "base/utf_string_conversions.h"
+#include "chrome/common/chrome_switches.h"
#include "googleurl/src/gurl.h"
#include "third_party/WebKit/WebKit/chromium/public/WebCString.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFileSystem.h"
#include "third_party/WebKit/WebKit/chromium/public/WebSecurityOrigin.h"
+#include "webkit/glue/webkit_glue.h"
+
+// We use some of WebKit types for conversions between storage identifiers
+// and origin URLs.
+using WebKit::WebFileSystem;
+using WebKit::WebSecurityOrigin;
+using WebKit::WebString;
const FilePath::CharType FileSystemHostContext::kFileSystemDirectory[] =
FILE_PATH_LITERAL("FileSystem");
@@ -18,10 +28,27 @@ const FilePath::CharType FileSystemHostContext::kFileSystemDirectory[] =
const char FileSystemHostContext::kPersistentName[] = "Persistent";
const char FileSystemHostContext::kTemporaryName[] = "Temporary";
+namespace {
+
+static inline std::string FilePathStringToASCII(
+ const FilePath::StringType& path_string) {
+#if defined(OS_WIN)
+ return WideToASCII(path_string);
+#elif defined(OS_POSIX)
+ return path_string;
+#endif
+}
+
+} // anonymous namespace
+
FileSystemHostContext::FileSystemHostContext(
const FilePath& data_path, bool is_incognito)
: base_path_(data_path.Append(kFileSystemDirectory)),
- is_incognito_(is_incognito) {
+ is_incognito_(is_incognito),
+ quota_manager_(new fileapi::FileSystemQuota()) {
+ const CommandLine& command_line = *CommandLine::ForCurrentProcess();
+ allow_file_access_from_files_ = command_line.HasSwitch(
+ switches::kAllowFileAccessFromFiles);
}
bool FileSystemHostContext::GetFileSystemRootPath(
@@ -30,6 +57,10 @@ bool FileSystemHostContext::GetFileSystemRootPath(
// TODO(kinuko): should return an isolated temporary file system space.
if (is_incognito_)
return false;
+
+ if (!IsAllowedScheme(origin_url))
+ return false;
+
std::string storage_identifier = GetStorageIdentifierFromURL(origin_url);
switch (type) {
case fileapi::kFileSystemTypeTemporary:
@@ -54,7 +85,87 @@ bool FileSystemHostContext::GetFileSystemRootPath(
bool FileSystemHostContext::CheckValidFileSystemPath(
const FilePath& path) const {
// Any paths that includes parent references are considered invalid.
- return !path.ReferencesParent() && base_path_.IsParent(path);
+ if (path.ReferencesParent())
+ return false;
+
+ // The path should be a child of the profile FileSystem path.
+ FilePath relative;
+ if (!base_path_.AppendRelativePath(path, &relative))
+ return false;
+
+ // The relative path from the profile FileSystem path should at least
+ // contains two components, one for storage identifier and the other for type.
+ std::vector<FilePath::StringType> components;
+ relative.GetComponents(&components);
+ if (components.size() < 2)
+ return false;
+
+ // The second component of the relative path to the root directory
+ // must be kPersistent or kTemporary.
+ if (!IsStringASCII(components[1]))
+ return false;
+ std::string ascii_type_component = FilePathStringToASCII(components[1]);
+ if (ascii_type_component != kPersistentName &&
+ ascii_type_component != kTemporaryName)
+ return false;
+
+ return true;
+}
+
+bool FileSystemHostContext::GetOriginFromPath(
+ const FilePath& path, GURL* origin_url) {
+ DCHECK(origin_url);
+ FilePath relative;
+ if (!base_path_.AppendRelativePath(path, &relative)) {
+ // The path should be a child of the profile's FileSystem path.
+ return false;
+ }
+ std::vector<FilePath::StringType> components;
+ relative.GetComponents(&components);
+ if (components.size() < 2) {
+ // The relative path should at least contain storage identifier and type.
+ return false;
+ }
+ WebSecurityOrigin web_security_origin =
+ WebSecurityOrigin::createFromDatabaseIdentifier(
+ webkit_glue::FilePathStringToWebString(components[0]));
+ *origin_url = GURL(web_security_origin.toString());
+
+ // We need this work-around for file:/// URIs as
+ // createFromDatabaseIdentifier returns empty origin_url for them.
+ if (allow_file_access_from_files_ && origin_url->spec().empty() &&
+ components[0].find(FILE_PATH_LITERAL("file")) == 0) {
+ *origin_url = GURL("file:///");
+ return true;
+ }
+
+ return IsAllowedScheme(*origin_url);
+}
+
+bool FileSystemHostContext::IsAllowedScheme(const GURL& url) const {
+ // Basically we only accept http or https. We allow file:// URLs
+ // only if --allow-file-access-from-files flag is given.
+ return url.SchemeIs("http") || url.SchemeIs("https") ||
+ (url.SchemeIsFile() && allow_file_access_from_files_);
+}
+
+bool FileSystemHostContext::CheckOriginQuota(const GURL& url, int64 growth) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // If allow-file-access-from-files flag is explicitly given and the scheme
+ // is file, always return true.
+ if (url.SchemeIsFile() && allow_file_access_from_files_)
+ return true;
+ return quota_manager_->CheckOriginQuota(url, growth);
+}
+
+void FileSystemHostContext::SetOriginQuotaUnlimited(const GURL& url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ quota_manager_->SetOriginQuotaUnlimited(url);
+}
+
+void FileSystemHostContext::ResetOriginQuotaUnlimited(const GURL& url) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ quota_manager_->ResetOriginQuotaUnlimited(url);
}
std::string FileSystemHostContext::GetStorageIdentifierFromURL(
@@ -64,7 +175,7 @@ std::string FileSystemHostContext::GetStorageIdentifierFromURL(
return web_security_origin.databaseIdentifier().utf8();
}
-COMPILE_ASSERT(int(WebKit::WebFileSystem::TypeTemporary) == \
+COMPILE_ASSERT(int(WebFileSystem::TypeTemporary) == \
int(fileapi::kFileSystemTypeTemporary), mismatching_enums);
-COMPILE_ASSERT(int(WebKit::WebFileSystem::TypePersistent) == \
+COMPILE_ASSERT(int(WebFileSystem::TypePersistent) == \
int(fileapi::kFileSystemTypePersistent), mismatching_enums);
diff --git a/chrome/browser/file_system/file_system_host_context.h b/chrome/browser/file_system/file_system_host_context.h
index e651a43..a1141c0 100644
--- a/chrome/browser/file_system/file_system_host_context.h
+++ b/chrome/browser/file_system/file_system_host_context.h
@@ -6,8 +6,11 @@
#define CHROME_BROWSER_FILE_SYSTEM_FILE_SYSTEM_HOST_CONTEXT_H_
#include "base/file_path.h"
+#include "base/gtest_prod_util.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
+#include "chrome/browser/chrome_thread.h"
+#include "webkit/fileapi/file_system_quota.h"
#include "webkit/fileapi/file_system_types.h"
class GURL;
@@ -15,7 +18,8 @@ class GURL;
// This is owned by profile and shared by all the FileSystemDispatcherHost
// that shared by the same profile.
class FileSystemHostContext
- : public base::RefCountedThreadSafe<FileSystemHostContext> {
+ : public base::RefCountedThreadSafe<FileSystemHostContext,
+ BrowserThread::DeleteOnIOThread> {
public:
FileSystemHostContext(const FilePath& data_path, bool is_incognito);
const FilePath& base_path() const { return base_path_; }
@@ -32,8 +36,19 @@ class FileSystemHostContext
// Check if the given |path| is in the FileSystem base directory.
bool CheckValidFileSystemPath(const FilePath& path) const;
- // Returns the storage identifier string for the given |url|.
- static std::string GetStorageIdentifierFromURL(const GURL& url);
+ // Retrieves the origin URL for the given |path| and populates
+ // |origin_url|. It returns false when the given |path| is not a
+ // valid filesystem path.
+ bool GetOriginFromPath(const FilePath& path, GURL* origin_url);
+
+ // Returns true if the given |url|'s scheme is allowed to access
+ // filesystem.
+ bool IsAllowedScheme(const GURL& url) const;
+
+ // Quota related methods.
+ bool CheckOriginQuota(const GURL& url, int64 growth);
+ void SetOriginQuotaUnlimited(const GURL& url);
+ void ResetOriginQuotaUnlimited(const GURL& url);
// The FileSystem directory name.
static const FilePath::CharType kFileSystemDirectory[];
@@ -42,8 +57,16 @@ class FileSystemHostContext
static const char kTemporaryName[];
private:
+ // Returns the storage identifier string for the given |url|.
+ static std::string GetStorageIdentifierFromURL(const GURL& url);
+
const FilePath base_path_;
const bool is_incognito_;
+ bool allow_file_access_from_files_;
+
+ scoped_ptr<fileapi::FileSystemQuota> quota_manager_;
+
+ FRIEND_TEST_ALL_PREFIXES(FileSystemHostContextTest, GetOriginFromPath);
DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemHostContext);
};
diff --git a/chrome/browser/file_system/file_system_host_context_unittest.cc b/chrome/browser/file_system/file_system_host_context_unittest.cc
index 3837e00..f91bb04 100644
--- a/chrome/browser/file_system/file_system_host_context_unittest.cc
+++ b/chrome/browser/file_system/file_system_host_context_unittest.cc
@@ -37,6 +37,9 @@ const struct RootPathTest {
false, "" },
{ fileapi::kFileSystemTypePersistent, true, "http://host:4/",
false, "" },
+ // We disallow file:// URIs to access filesystem.
+ { fileapi::kFileSystemTypeTemporary, false, "file:///some/path", false, "" },
+ { fileapi::kFileSystemTypePersistent, false, "file:///some/path", false, "" },
};
const struct CheckValidPathTest {
diff --git a/webkit/fileapi/file_system_quota.cc b/webkit/fileapi/file_system_quota.cc
new file mode 100644
index 0000000..eb69beb
--- /dev/null
+++ b/webkit/fileapi/file_system_quota.cc
@@ -0,0 +1,35 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/fileapi/file_system_quota.h"
+
+#include "base/file_path.h"
+#include "base/file_util_proxy.h"
+#include "base/ref_counted.h"
+#include "base/scoped_callback_factory.h"
+
+namespace fileapi {
+
+const int64 FileSystemQuota::kUnknownSize = -1;
+
+bool FileSystemQuota::CheckOriginQuota(const GURL& origin, int64) {
+ return CheckIfOriginGrantedUnlimitedQuota(origin);
+}
+
+void FileSystemQuota::SetOriginQuotaUnlimited(const GURL& origin) {
+ DCHECK(origin == origin.GetOrigin());
+ unlimited_quota_origins_.insert(origin);
+}
+
+void FileSystemQuota::ResetOriginQuotaUnlimited(const GURL& origin) {
+ DCHECK(origin == origin.GetOrigin());
+ unlimited_quota_origins_.erase(origin);
+}
+
+bool FileSystemQuota::CheckIfOriginGrantedUnlimitedQuota(const GURL& origin) {
+ std::set<GURL>::const_iterator found = unlimited_quota_origins_.find(origin);
+ return (found != unlimited_quota_origins_.end());
+}
+
+} // namespace fileapi
diff --git a/webkit/fileapi/file_system_quota.h b/webkit/fileapi/file_system_quota.h
new file mode 100644
index 0000000..80888ed1
--- /dev/null
+++ b/webkit/fileapi/file_system_quota.h
@@ -0,0 +1,42 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef WEBKIT_FILEAPI_FILE_SYSTEM_QUOTA_H_
+#define WEBKIT_FILEAPI_FILE_SYSTEM_QUOTA_H_
+
+#include <set>
+
+#include "base/basictypes.h"
+#include "googleurl/src/gurl.h"
+
+namespace fileapi {
+
+// A quota manager for FileSystem. For now it has little implementation
+// and just allows unlimited quota for apps.
+class FileSystemQuota {
+ public:
+ FileSystemQuota() { }
+ static const int64 kUnknownSize;
+
+ // Checks if the origin can grow its usage by |growth| bytes.
+ // This only performs in-memory check and returns immediately.
+ // For now it just returns false for any origins (regardless of the size)
+ // that are not in the in-memory unlimited_quota_origins map.
+ bool CheckOriginQuota(const GURL& origin, int64 growth);
+
+ // Maintains origins in memory that are allowed to have unlimited quota.
+ void SetOriginQuotaUnlimited(const GURL& origin);
+ void ResetOriginQuotaUnlimited(const GURL& origin);
+ bool CheckIfOriginGrantedUnlimitedQuota(const GURL& origin);
+
+ private:
+ // For some extensions/apps we allow unlimited quota.
+ std::set<GURL> unlimited_quota_origins_;
+
+ DISALLOW_COPY_AND_ASSIGN(FileSystemQuota);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_FILEAPI_FILE_SYSTEM_QUOTA_H_
diff --git a/webkit/fileapi/file_system_quota_unittest.cc b/webkit/fileapi/file_system_quota_unittest.cc
new file mode 100644
index 0000000..0c505cd
--- /dev/null
+++ b/webkit/fileapi/file_system_quota_unittest.cc
@@ -0,0 +1,146 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "webkit/fileapi/file_system_quota.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/scoped_ptr.h"
+#include "base/string_number_conversions.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+using namespace fileapi;
+
+class FileSystemQuotaTest : public testing::Test {
+ public:
+ FileSystemQuotaTest() { }
+
+ void SetUp() {
+ quota_.reset(new FileSystemQuota);
+ }
+
+ FileSystemQuota* quota() const { return quota_.get(); }
+
+ protected:
+ scoped_ptr<FileSystemQuota> quota_;
+ DISALLOW_COPY_AND_ASSIGN(FileSystemQuotaTest);
+};
+
+namespace {
+
+static const char* const kTestOrigins[] = {
+ "https://a.com/",
+ "http://b.com/",
+ "http://c.com:1/",
+ "file:///",
+};
+
+} // anonymous namespace
+
+TEST_F(FileSystemQuotaTest, CheckOriginQuotaNotAllowed) {
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaNotAllowed #"
+ << i << " " << kTestOrigins[i]);
+ // Should fail no matter how much size is requested.
+ EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), -1));
+ EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), 0));
+ EXPECT_FALSE(quota()->CheckOriginQuota(GURL(kTestOrigins[i]), 100));
+ }
+}
+
+TEST_F(FileSystemQuotaTest, CheckOriginQuotaUnlimited) {
+ // Tests if SetOriginQuotaUnlimited and ResetOriginQuotaUnlimited
+ // are working as expected.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaUnlimited #"
+ << i << " " << kTestOrigins[i]);
+ GURL url(kTestOrigins[i]);
+ EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
+
+ quota()->SetOriginQuotaUnlimited(url);
+ EXPECT_TRUE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ EXPECT_TRUE(quota()->CheckOriginQuota(url, -1));
+ EXPECT_TRUE(quota()->CheckOriginQuota(url, 0));
+ EXPECT_TRUE(quota()->CheckOriginQuota(url, 100));
+
+ quota()->ResetOriginQuotaUnlimited(url);
+ EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, -1));
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 100));
+ }
+}
+
+TEST_F(FileSystemQuotaTest, CheckOriginQuotaWithMixedSet) {
+ // Tests setting unlimited quota for some urls doesn't affect
+ // other urls.
+ GURL test_url1("http://foo.bar.com/");
+ GURL test_url2("http://example.com/");
+ quota()->SetOriginQuotaUnlimited(test_url1);
+ quota()->SetOriginQuotaUnlimited(test_url2);
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ SCOPED_TRACE(testing::Message() << "CheckOriginQuotaMixedSet #"
+ << i << " " << kTestOrigins[i]);
+ GURL url(kTestOrigins[i]);
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
+ EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ }
+}
+
+TEST_F(FileSystemQuotaTest, CheckOriginQuotaMixedWithDifferentScheme) {
+ // Tests setting unlimited quota for urls doesn't affect
+ // pages in the same hosts but with different scheme.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ GURL url(kTestOrigins[i]);
+ if (url.SchemeIsFile())
+ continue;
+ DCHECK(url == url.GetOrigin());
+ std::string new_scheme = "https";
+ if (url.SchemeIsSecure())
+ new_scheme = "http";
+ else
+ DCHECK(url.SchemeIs("http"));
+ std::string new_url_string = new_scheme + "://" + url.host();
+ if (url.has_port())
+ new_url_string += ":" + url.port();
+ quota()->SetOriginQuotaUnlimited(GURL(new_url_string));
+ }
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ SCOPED_TRACE(testing::Message()
+ << "CheckOriginQuotaMixedWithDifferentScheme #"
+ << i << " " << kTestOrigins[i]);
+ GURL url(kTestOrigins[i]);
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
+ EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ }
+}
+
+TEST_F(FileSystemQuotaTest, CheckOriginQuotaMixedWithDifferentPort) {
+ // Tests setting unlimited quota for urls doesn't affect
+ // pages in the same scheme/hosts but with different port number.
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ GURL url(kTestOrigins[i]);
+ if (url.SchemeIsFile())
+ continue;
+ DCHECK(url == url.GetOrigin());
+ int port = 81;
+ if (url.has_port())
+ port = url.IntPort() + 1;
+ GURL new_url(url.scheme() + "://" + url.host() + ":" +
+ base::IntToString(port));
+ quota()->SetOriginQuotaUnlimited(new_url);
+ }
+
+ for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestOrigins); ++i) {
+ SCOPED_TRACE(testing::Message()
+ << "CheckOriginQuotaMixedWithDifferentPort #"
+ << i << " " << kTestOrigins[i]);
+ GURL url(kTestOrigins[i]);
+ EXPECT_FALSE(quota()->CheckOriginQuota(url, 0));
+ EXPECT_FALSE(quota()->CheckIfOriginGrantedUnlimitedQuota(url));
+ }
+}
diff --git a/webkit/fileapi/webkit_fileapi.gypi b/webkit/fileapi/webkit_fileapi.gypi
index a795da4..f01e9db 100644
--- a/webkit/fileapi/webkit_fileapi.gypi
+++ b/webkit/fileapi/webkit_fileapi.gypi
@@ -17,6 +17,8 @@
'file_system_callback_dispatcher.h',
'file_system_operation.cc',
'file_system_operation.h',
+ 'file_system_quota.cc',
+ 'file_system_quota.h',
'file_system_types.h',
'file_writer_delegate.cc',
'file_writer_delegate.h',
diff --git a/webkit/glue/webkit_glue.cc b/webkit/glue/webkit_glue.cc
index f7f60aa..a58ff1b 100644
--- a/webkit/glue/webkit_glue.cc
+++ b/webkit/glue/webkit_glue.cc
@@ -330,6 +330,10 @@ WebKit::WebFileError PlatformFileErrorToWebFileError(
return WebKit::WebFileErrorInvalidState;
case base::PLATFORM_FILE_ERROR_ABORT:
return WebKit::WebFileErrorAbort;
+ case base::PLATFORM_FILE_ERROR_SECURITY:
+ return WebKit::WebFileErrorSecurity;
+ case base::PLATFORM_FILE_ERROR_NO_SPACE:
+ return WebKit::WebFileErrorQuotaExceeded;
default:
return WebKit::WebFileErrorInvalidModification;
}
diff --git a/webkit/tools/test_shell/test_shell.gypi b/webkit/tools/test_shell/test_shell.gypi
index d9efb30..4ac1faa 100644
--- a/webkit/tools/test_shell/test_shell.gypi
+++ b/webkit/tools/test_shell/test_shell.gypi
@@ -376,6 +376,7 @@
'../../database/database_util_unittest.cc',
'../../database/quota_table_unittest.cc',
'../../fileapi/file_system_operation_unittest.cc',
+ '../../fileapi/file_system_quota_unittest.cc',
'../../glue/bookmarklet_unittest.cc',
'../../glue/context_menu_unittest.cc',
'../../glue/cpp_bound_class_unittest.cc',