diff options
-rw-r--r-- | chrome/browser/DEPS | 1 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_special_storage_policy.cc | 93 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_special_storage_policy.h | 53 | ||||
-rw-r--r-- | chrome/browser/extensions/extension_special_storage_policy_unittest.cc | 157 | ||||
-rw-r--r-- | chrome/chrome_browser.gypi | 2 | ||||
-rw-r--r-- | chrome/chrome_tests.gypi | 1 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 38 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 3 | ||||
-rw-r--r-- | chrome/common/extensions/url_pattern.cc | 17 | ||||
-rw-r--r-- | chrome/common/extensions/url_pattern.h | 10 | ||||
-rw-r--r-- | webkit/quota/special_storage_policy.h | 31 |
11 files changed, 381 insertions, 25 deletions
diff --git a/chrome/browser/DEPS b/chrome/browser/DEPS index 757e0b4..064caf9 100644 --- a/chrome/browser/DEPS +++ b/chrome/browser/DEPS @@ -20,6 +20,7 @@ include_rules = [ "+webkit/database", "+webkit/glue", # Defines some types that are marshalled over IPC. "+webkit/plugins", # Defines some types that are marshalled over IPC. + "+webkit/quota", "+xib_localizers", # For generated mac localization helpers # Other libraries. diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc new file mode 100644 index 0000000..1a840fc --- /dev/null +++ b/chrome/browser/extensions/extension_special_storage_policy.cc @@ -0,0 +1,93 @@ +// 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. + +#include "chrome/browser/extensions/extension_special_storage_policy.h" + +#include "base/logging.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/url_constants.h" + +bool ExtensionSpecialStoragePolicy::IsStorageProtected(const GURL& origin) { + if (origin.SchemeIs(chrome::kExtensionScheme)) + return true; + base::AutoLock locker(lock_); + return protected_apps_.Contains(origin); +} + +bool ExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) { + base::AutoLock locker(lock_); + return unlimited_extensions_.Contains(origin); +} + +void ExtensionSpecialStoragePolicy::GrantRightsForExtension( + const Extension* extension) { + DCHECK(extension); + if (!extension->is_hosted_app() && + !extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) { + return; + } + base::AutoLock locker(lock_); + if (extension->is_hosted_app()) + protected_apps_.Add(extension); + if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) + unlimited_extensions_.Add(extension); +} + +void ExtensionSpecialStoragePolicy::RevokeRightsForExtension( + const Extension* extension) { + DCHECK(extension); + if (!extension->is_hosted_app() && + !extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) { + return; + } + base::AutoLock locker(lock_); + if (extension->is_hosted_app()) + protected_apps_.Remove(extension); + if (extension->HasApiPermission(Extension::kUnlimitedStoragePermission)) + unlimited_extensions_.Remove(extension); +} + +void ExtensionSpecialStoragePolicy::RevokeRightsForAllExtensions() { + base::AutoLock locker(lock_); + protected_apps_.Clear(); + unlimited_extensions_.Clear(); +} + +//----------------------------------------------------------------------------- +// SpecialCollection helper class +//----------------------------------------------------------------------------- + +bool ExtensionSpecialStoragePolicy::SpecialCollection::Contains( + const GURL& origin) { + CachedResults::const_iterator found = cached_resuts_.find(origin); + if (found != cached_resuts_.end()) + return found->second; + + for (Extensions::const_iterator iter = extensions_.begin(); + iter != extensions_.end(); ++iter) { + if ((*iter)->OverlapsWithOrigin(origin)) { + cached_resuts_[origin] = true; + return true; + } + } + cached_resuts_[origin] = false; + return false; +} + +void ExtensionSpecialStoragePolicy::SpecialCollection::Add( + const Extension* extension) { + cached_resuts_.clear(); + extensions_.insert(extension); +} + +void ExtensionSpecialStoragePolicy::SpecialCollection::Remove( + const Extension* extension) { + cached_resuts_.clear(); + extensions_.erase(extension); +} + +void ExtensionSpecialStoragePolicy::SpecialCollection::Clear() { + cached_resuts_.clear(); + extensions_.clear(); +} diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h new file mode 100644 index 0000000..72ab89b --- /dev/null +++ b/chrome/browser/extensions/extension_special_storage_policy.h @@ -0,0 +1,53 @@ +// 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. + +#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_SPECIAL_STORAGE_POLICY_H_ +#define CHROME_BROWSER_EXTENSIONS_EXTENSION_SPECIAL_STORAGE_POLICY_H_ +#pragma once + +#include <map> +#include <set> + +#include "base/synchronization/lock.h" +#include "googleurl/src/gurl.h" +#include "webkit/quota/special_storage_policy.h" + +class Extension; + +// Special rights are granted to 'extensions' and 'applications'. The +// storage subsystems and the browsing data remover query this interface +// to determine which origins have these rights. +class ExtensionSpecialStoragePolicy : public quota::SpecialStoragePolicy { + public: + // SpecialStoragePolicy methods used by storage subsystems and the browsing + // data remover. These methods are safe to call on any thread. + virtual bool IsStorageProtected(const GURL& origin); + virtual bool IsStorageUnlimited(const GURL& origin); + + // Methods used by the ExtensionService to populate this class. + void GrantRightsForExtension(const Extension* extension); + void RevokeRightsForExtension(const Extension* extension); + void RevokeRightsForAllExtensions(); + + private: + class SpecialCollection { + public: + bool Contains(const GURL& origin); + void Add(const Extension* extension); + void Remove(const Extension* extension); + void Clear(); + + private: + typedef std::map<GURL, bool> CachedResults; + typedef std::set<const Extension*> Extensions; + Extensions extensions_; + CachedResults cached_resuts_; + }; + + base::Lock lock_; // Synchronize all access to the collections. + SpecialCollection protected_apps_; + SpecialCollection unlimited_extensions_; +}; + +#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SPECIAL_STORAGE_POLICY_H_ diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc new file mode 100644 index 0000000..9597fb8 --- /dev/null +++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc @@ -0,0 +1,157 @@ +// 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. + +#include "base/values.h" +#include "chrome/browser/extensions/extension_special_storage_policy.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/common/extensions/extension_constants.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace keys = extension_manifest_keys; + +class ExtensionSpecialStoragePolicyTest : public testing::Test { + protected: + scoped_refptr<Extension> CreateProtectedApp() { +#if defined(OS_WIN) + FilePath path(FILE_PATH_LITERAL("c:\\foo")); +#elif defined(OS_POSIX) + FilePath path(FILE_PATH_LITERAL("/foo")); +#endif + DictionaryValue manifest; + manifest.SetString(keys::kName, "Protected"); + manifest.SetString(keys::kVersion, "1"); + manifest.SetString(keys::kLaunchWebURL, "http://explicit/protected/start"); + ListValue* list = new ListValue(); + list->Append(Value::CreateStringValue("http://explicit/protected")); + list->Append(Value::CreateStringValue("*://*.wildcards/protected")); + manifest.Set(keys::kWebURLs, list); + std::string error; + scoped_refptr<Extension> protected_app = Extension::Create( + path, Extension::INVALID, manifest, false, &error); + EXPECT_TRUE(protected_app.get()) << error; + return protected_app; + } + + scoped_refptr<Extension> CreateUnlimitedApp() { +#if defined(OS_WIN) + FilePath path(FILE_PATH_LITERAL("c:\\bar")); +#elif defined(OS_POSIX) + FilePath path(FILE_PATH_LITERAL("/bar")); +#endif + DictionaryValue manifest; + manifest.SetString(keys::kName, "Unlimited"); + manifest.SetString(keys::kVersion, "1"); + manifest.SetString(keys::kLaunchWebURL, "http://explicit/unlimited/start"); + ListValue* list = new ListValue(); + list->Append(Value::CreateStringValue("unlimitedStorage")); + manifest.Set(keys::kPermissions, list); + list = new ListValue(); + list->Append(Value::CreateStringValue("http://explicit/unlimited")); + list->Append(Value::CreateStringValue("*://*.wildcards/unlimited")); + manifest.Set(keys::kWebURLs, list); + std::string error; + scoped_refptr<Extension> unlimited_app = Extension::Create( + path, Extension::INVALID, manifest, false, &error); + EXPECT_TRUE(unlimited_app.get()) << error; + return unlimited_app; + } +}; + +TEST_F(ExtensionSpecialStoragePolicyTest, EmptyPolicy) { + const GURL kHttpUrl("http://foo"); + const GURL kExtensionUrl("chrome-extension://bar"); + + scoped_refptr<ExtensionSpecialStoragePolicy> policy( + new ExtensionSpecialStoragePolicy); + + ASSERT_FALSE(policy->IsStorageUnlimited(kHttpUrl)); + ASSERT_FALSE(policy->IsStorageUnlimited(kHttpUrl)); // test cached result + ASSERT_FALSE(policy->IsStorageUnlimited(kExtensionUrl)); + ASSERT_FALSE(policy->IsStorageProtected(kHttpUrl)); + + // This one is just based on the scheme. + ASSERT_TRUE(policy->IsStorageProtected(kExtensionUrl)); +} + + +TEST_F(ExtensionSpecialStoragePolicyTest, AppWithProtectedStorage) { + scoped_refptr<Extension> extension(CreateProtectedApp()); + scoped_refptr<ExtensionSpecialStoragePolicy> policy( + new ExtensionSpecialStoragePolicy); + policy->GrantRightsForExtension(extension); + EXPECT_FALSE(policy->IsStorageUnlimited(extension->url())); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit:6000/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://not_listed/"))); + + policy->RevokeRightsForExtension(extension); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("https://bar.wildcards/"))); +} + +TEST_F(ExtensionSpecialStoragePolicyTest, AppWithUnlimitedStorage) { + scoped_refptr<Extension> extension(CreateUnlimitedApp()); + scoped_refptr<ExtensionSpecialStoragePolicy> policy( + new ExtensionSpecialStoragePolicy); + policy->GrantRightsForExtension(extension); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit:6000/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://not_listed/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(extension->url())); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("http://explicit:6000/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("https://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://not_listed/"))); + + policy->RevokeRightsForExtension(extension); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://explicit/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("https://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("https://bar.wildcards/"))); +} + +TEST_F(ExtensionSpecialStoragePolicyTest, OverlappingApps) { + scoped_refptr<Extension> protected_app(CreateProtectedApp()); + scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp()); + scoped_refptr<ExtensionSpecialStoragePolicy> policy( + new ExtensionSpecialStoragePolicy); + policy->GrantRightsForExtension(protected_app); + policy->GrantRightsForExtension(unlimited_app); + + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit:6000/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://not_listed/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("http://explicit:6000/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("https://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageUnlimited(GURL("https://bar.wildcards/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://not_listed/"))); + + policy->RevokeRightsForExtension(unlimited_app); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://explicit/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("https://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageUnlimited(GURL("https://bar.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("http://foo.wildcards/"))); + EXPECT_TRUE(policy->IsStorageProtected(GURL("https://bar.wildcards/"))); + + policy->RevokeRightsForExtension(protected_app); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://explicit/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("http://foo.wildcards/"))); + EXPECT_FALSE(policy->IsStorageProtected(GURL("https://bar.wildcards/"))); +} diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 7026b30..8a2ad56 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1178,6 +1178,8 @@ 'browser/extensions/extension_service.h', 'browser/extensions/extension_sidebar_api.cc', 'browser/extensions/extension_sidebar_api.h', + 'browser/extensions/extension_special_storage_policy.cc', + 'browser/extensions/extension_special_storage_policy.h', 'browser/extensions/extension_tabs_module.cc', 'browser/extensions/extension_tabs_module.h', 'browser/extensions/extension_tabs_module_constants.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 7378bde..718069e 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1288,6 +1288,7 @@ 'browser/extensions/extension_omnibox_unittest.cc', 'browser/extensions/extension_service_unittest.cc', 'browser/extensions/extension_service_unittest.h', + 'browser/extensions/extension_special_storage_policy_unittest.cc', 'browser/extensions/extension_ui_unittest.cc', 'browser/extensions/extension_updater_unittest.cc', 'browser/extensions/extension_webnavigation_unittest.cc', diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index fb96f92..298984b 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -907,8 +907,8 @@ bool Extension::LoadExtent(const DictionaryValue* manifest, return false; } - // Do not allow authors to claim "<all_urls>". That would make no sense. - if (pattern.match_all_urls()) { + // Do not allow authors to claim "<all_urls>" or "*" for host. + if (pattern.match_all_urls() || pattern.host().empty()) { *error = ExtensionErrorUtils::FormatErrorMessage(value_error, base::UintToString(i)); return false; @@ -921,7 +921,7 @@ bool Extension::LoadExtent(const DictionaryValue* manifest, base::UintToString(i)); return false; } - pattern.set_path(pattern.path() + '*'); + pattern.SetPath(pattern.path() + '*'); extent->AddPattern(pattern); } @@ -983,7 +983,7 @@ bool Extension::LoadLaunchURL(const DictionaryValue* manifest, return false; } pattern.set_host(launch_url.host()); - pattern.set_path("/*"); + pattern.SetPath("/*"); extent_.AddPattern(pattern); } @@ -996,9 +996,9 @@ bool Extension::LoadLaunchURL(const DictionaryValue* manifest, if (gallery_url.is_valid()) { launch_web_url_ = gallery_url.spec(); - URLPattern pattern(URLPattern::SCHEME_HTTP | URLPattern::SCHEME_HTTPS); + URLPattern pattern(kValidWebExtentSchemes); pattern.Parse(gallery_url.spec()); - pattern.set_path(pattern.path() + '*'); + pattern.SetPath(pattern.path() + '*'); extent_.AddPattern(pattern); } } @@ -1305,8 +1305,7 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, manifest_value_.reset(source.DeepCopy()); // Initialize the URL. - extension_url_ = - Extension::GetBaseURLFromExtensionId(id()); + extension_url_ = Extension::GetBaseURLFromExtensionId(id()); // Initialize version. std::string version_str; @@ -1809,7 +1808,6 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, URLPattern pattern = URLPattern(CanExecuteScriptEverywhere() ? URLPattern::SCHEME_ALL : kValidHostPermissionSchemes); - if (URLPattern::PARSE_SUCCESS == pattern.Parse(permission_str)) { if (!CanSpecifyHostPermission(pattern)) { *error = ExtensionErrorUtils::FormatErrorMessage( @@ -1819,7 +1817,7 @@ bool Extension::InitFromValue(const DictionaryValue& source, bool require_key, // The path component is not used for host permissions, so we force it // to match all paths. - pattern.set_path("/*"); + pattern.SetPath("/*"); host_permissions_.push_back(pattern); } @@ -2360,6 +2358,26 @@ bool Extension::UpdatesFromGallery() const { update_url() == GalleryUpdateUrl(true); } +bool Extension::OverlapsWithOrigin(const GURL& origin) const { + if (url() == origin) + return true; + + if (web_extent().is_empty()) + return false; + + // Note: patterns and extents ignore port numbers. + URLPattern origin_only_pattern(kValidWebExtentSchemes); + if (!origin_only_pattern.SetScheme(origin.scheme())) + return false; + origin_only_pattern.set_host(origin.host()); + origin_only_pattern.SetPath("/*"); + + ExtensionExtent origin_only_pattern_list; + origin_only_pattern_list.AddPattern(origin_only_pattern); + + return web_extent().OverlapsWith(origin_only_pattern_list); +} + ExtensionInfo::ExtensionInfo(const DictionaryValue* manifest, const std::string& id, const FilePath& path, diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index 0edb6e2..63a2bf9 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -402,6 +402,9 @@ class Extension : public base::RefCountedThreadSafe<Extension> { // gallery. bool UpdatesFromGallery() const; + // Returns true if this extension or app includes areas within |origin|. + bool OverlapsWithOrigin(const GURL& origin) const; + // Accessors: const FilePath& path() const { return path_; } diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc index b6e09b7..6dc3578 100644 --- a/chrome/common/extensions/url_pattern.cc +++ b/chrome/common/extensions/url_pattern.cc @@ -72,7 +72,7 @@ URLPattern::ParseResult URLPattern::Parse(const std::string& pattern) { match_subdomains_ = true; scheme_ = "*"; host_.clear(); - path_ = "/*"; + SetPath("/*"); return PARSE_SUCCESS; } @@ -140,7 +140,7 @@ URLPattern::ParseResult URLPattern::Parse(const std::string& pattern) { path_start_pos = host_end_pos; } - path_ = pattern.substr(path_start_pos); + SetPath(pattern.substr(path_start_pos)); return PARSE_SUCCESS; } @@ -167,6 +167,13 @@ bool URLPattern::IsValidScheme(const std::string& scheme) const { return false; } +void URLPattern::SetPath(const std::string& path) { + path_ = path; + path_escaped_ = path_; + ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\"); + ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?"); +} + bool URLPattern::MatchesUrl(const GURL &test) const { if (!MatchesScheme(test.scheme())) return false; @@ -230,12 +237,6 @@ bool URLPattern::MatchesHost(const GURL& test) const { } bool URLPattern::MatchesPath(const std::string& test) const { - if (path_escaped_.empty()) { - path_escaped_ = path_; - ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\"); - ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?"); - } - if (!MatchPattern(test, path_escaped_)) return false; diff --git a/chrome/common/extensions/url_pattern.h b/chrome/common/extensions/url_pattern.h index 56deed5..723dc2c 100644 --- a/chrome/common/extensions/url_pattern.h +++ b/chrome/common/extensions/url_pattern.h @@ -140,10 +140,7 @@ class URLPattern { // Gets the path the pattern matches with the leading slash. This can have // embedded asterisks which are interpreted using glob rules. const std::string& path() const { return path_; } - void set_path(const std::string& path) { - path_ = path; - path_escaped_ = ""; - } + void SetPath(const std::string& path); // Returns true if this pattern matches all urls. bool match_all_urls() const { return match_all_urls_; } @@ -241,9 +238,8 @@ class URLPattern { std::string path_; // The path with "?" and "\" characters escaped for use with the - // MatchPattern() function. This is populated lazily, the first time it is - // needed. - mutable std::string path_escaped_; + // MatchPattern() function. + std::string path_escaped_; }; typedef std::vector<URLPattern> URLPatternList; diff --git a/webkit/quota/special_storage_policy.h b/webkit/quota/special_storage_policy.h new file mode 100644 index 0000000..1f17dac --- /dev/null +++ b/webkit/quota/special_storage_policy.h @@ -0,0 +1,31 @@ +// 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_QUOTA_SPECIAL_STORAGE_POLICY_H_ +#define WEBKIT_QUOTA_SPECIAL_STORAGE_POLICY_H_ + +#include "base/ref_counted.h" + +class GURL; + +namespace quota { + +// Special rights are granted to 'extensions' and 'applications'. The +// storage subsystems query this interface to determine which origins +// have these rights. Chrome provides an impl that is cognizant of what +// is currently installed in the extensions system. +// An implementation must be thread-safe. +class SpecialStoragePolicy + : public base::RefCountedThreadSafe<SpecialStoragePolicy> { + public: + // Protected storage is not subject to removal by the browsing data remover. + virtual bool IsStorageProtected(const GURL& origin) = 0; + + // Unlimited storage is not subject to 'quotas'. + virtual bool IsStorageUnlimited(const GURL& origin) = 0; +}; + +} // namespace quota + +#endif // WEBKIT_QUOTA_SPECIAL_STORAGE_POLICY_H_ |