summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/DEPS1
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.cc93
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.h53
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy_unittest.cc157
-rw-r--r--chrome/chrome_browser.gypi2
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/common/extensions/extension.cc38
-rw-r--r--chrome/common/extensions/extension.h3
-rw-r--r--chrome/common/extensions/url_pattern.cc17
-rw-r--r--chrome/common/extensions/url_pattern.h10
-rw-r--r--webkit/quota/special_storage_policy.h31
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_