summaryrefslogtreecommitdiffstats
path: root/chrome/common
diff options
context:
space:
mode:
authorericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 16:56:58 +0000
committerericu@google.com <ericu@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2012-03-24 16:56:58 +0000
commit932df839a6562730cd741f24fc469606d9d9ffb7 (patch)
tree2c244f93639d2c0f50e6e917cc01ea33fd637a43 /chrome/common
parent3bfc16cf47deae24f43b3967edf769112a674482 (diff)
downloadchromium_src-932df839a6562730cd741f24fc469606d9d9ffb7.zip
chromium_src-932df839a6562730cd741f24fc469606d9d9ffb7.tar.gz
chromium_src-932df839a6562730cd741f24fc469606d9d9ffb7.tar.bz2
Add full support for filesystem URLs.
BUG=114484 TEST=existing filesystem tests don't break Review URL: https://chromiumcodereview.appspot.com/7811006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@128753 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/common')
-rw-r--r--chrome/common/content_settings_pattern.cc64
-rw-r--r--chrome/common/content_settings_pattern_unittest.cc61
-rw-r--r--chrome/common/extensions/extension.cc19
-rw-r--r--chrome/common/extensions/extension_manifests_unittest.cc1
-rw-r--r--chrome/common/extensions/url_pattern.cc26
-rw-r--r--chrome/common/extensions/url_pattern.h16
-rw-r--r--chrome/common/extensions/url_pattern_unittest.cc24
7 files changed, 179 insertions, 32 deletions
diff --git a/chrome/common/content_settings_pattern.cc b/chrome/common/content_settings_pattern.cc
index 8008cba..8feef19 100644
--- a/chrome/common/content_settings_pattern.cc
+++ b/chrome/common/content_settings_pattern.cc
@@ -313,28 +313,33 @@ ContentSettingsPattern ContentSettingsPattern::FromURL(
scoped_ptr<ContentSettingsPattern::BuilderInterface> builder(
ContentSettingsPattern::CreateBuilder(false));
- if (url.SchemeIsFile()) {
- builder->WithScheme(url.scheme())->WithPath(url.path());
+ const GURL* local_url = &url;
+ if (url.SchemeIsFileSystem() && url.inner_url()) {
+ local_url = url.inner_url();
+ }
+ if (local_url->SchemeIsFile()) {
+ builder->WithScheme(local_url->scheme())->WithPath(local_url->path());
} else {
// Please keep the order of the ifs below as URLs with an IP as host can
// also have a "http" scheme.
- if (url.HostIsIPAddress()) {
- builder->WithScheme(url.scheme())->WithHost(url.host());
- } else if (url.SchemeIs(chrome::kHttpScheme)) {
- builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(url.host());
- } else if (url.SchemeIs(chrome::kHttpsScheme)) {
- builder->WithScheme(url.scheme())->WithDomainWildcard()->WithHost(
- url.host());
+ if (local_url->HostIsIPAddress()) {
+ builder->WithScheme(local_url->scheme())->WithHost(local_url->host());
+ } else if (local_url->SchemeIs(chrome::kHttpScheme)) {
+ builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(
+ local_url->host());
+ } else if (local_url->SchemeIs(chrome::kHttpsScheme)) {
+ builder->WithScheme(local_url->scheme())->WithDomainWildcard()->WithHost(
+ local_url->host());
} else {
// Unsupported scheme
}
- if (url.port().empty()) {
- if (url.SchemeIs(chrome::kHttpsScheme))
+ if (local_url->port().empty()) {
+ if (local_url->SchemeIs(chrome::kHttpsScheme))
builder->WithPort(GetDefaultPort(chrome::kHttpsScheme));
else
builder->WithPortWildcard();
} else {
- builder->WithPort(url.port());
+ builder->WithPort(local_url->port());
}
}
return builder->Build();
@@ -346,14 +351,18 @@ ContentSettingsPattern ContentSettingsPattern::FromURLNoWildcard(
scoped_ptr<ContentSettingsPattern::BuilderInterface> builder(
ContentSettingsPattern::CreateBuilder(false));
- if (url.SchemeIsFile()) {
- builder->WithScheme(url.scheme())->WithPath(url.path());
+ const GURL* local_url = &url;
+ if (url.SchemeIsFileSystem() && url.inner_url()) {
+ local_url = url.inner_url();
+ }
+ if (local_url->SchemeIsFile()) {
+ builder->WithScheme(local_url->scheme())->WithPath(local_url->path());
} else {
- builder->WithScheme(url.scheme())->WithHost(url.host());
- if (url.port().empty()) {
- builder->WithPort(GetDefaultPort(url.scheme()));
+ builder->WithScheme(local_url->scheme())->WithHost(local_url->host());
+ if (local_url->port().empty()) {
+ builder->WithPort(GetDefaultPort(local_url->scheme()));
} else {
- builder->WithPort(url.port());
+ builder->WithPort(local_url->port());
}
}
return builder->Build();
@@ -414,8 +423,13 @@ bool ContentSettingsPattern::Matches(
if (!is_valid_)
return false;
+ const GURL* local_url = &url;
+ if (url.SchemeIsFileSystem() && url.inner_url()) {
+ local_url = url.inner_url();
+ }
+
// Match the scheme part.
- const std::string scheme(url.scheme());
+ const std::string scheme(local_url->scheme());
if (!parts_.is_scheme_wildcard &&
parts_.scheme != scheme) {
return false;
@@ -423,11 +437,17 @@ bool ContentSettingsPattern::Matches(
// File URLs have no host. Matches if the pattern has the path wildcard set,
// or if the path in the URL is identical to the one in the pattern.
+ // For filesystem:file URLs, the path used is the filesystem type, so all
+ // filesystem:file:///temporary/... are equivalent.
+ // TODO(markusheintz): Content settings should be defined for all files on
+ // a machine. Unless there is a good use case for supporting paths for file
+ // patterns, stop supporting path for file patterns.
if (!parts_.is_scheme_wildcard && scheme == chrome::kFileScheme)
- return parts_.is_path_wildcard || parts_.path == std::string(url.path());
+ return parts_.is_path_wildcard ||
+ parts_.path == std::string(local_url->path());
// Match the host part.
- const std::string host(net::TrimEndingDot(url.host()));
+ const std::string host(net::TrimEndingDot(local_url->host()));
if (!parts_.has_domain_wildcard) {
if (parts_.host != host)
return false;
@@ -441,7 +461,7 @@ bool ContentSettingsPattern::Matches(
return true;
// Match the port part.
- std::string port(url.port());
+ std::string port(local_url->port());
// Use the default port if the port string is empty. GURL returns an empty
// string if no port at all was specified or if the default port was
diff --git a/chrome/common/content_settings_pattern_unittest.cc b/chrome/common/content_settings_pattern_unittest.cc
index f0eeca5..bd79338 100644
--- a/chrome/common/content_settings_pattern_unittest.cc
+++ b/chrome/common/content_settings_pattern_unittest.cc
@@ -73,6 +73,7 @@ TEST(ContentSettingsPatternTest, FromURL) {
pattern = ContentSettingsPattern::FromURL(GURL("https://www.google.com:443"));
EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com")));
+ EXPECT_TRUE(pattern.Matches(GURL("https://foo.www.google.com")));
EXPECT_TRUE(pattern.Matches(GURL("https://www.google.com:443")));
EXPECT_FALSE(pattern.Matches(GURL("https://www.google.com:444")));
EXPECT_FALSE(pattern.Matches(GURL("http://www.google.com:443")));
@@ -89,6 +90,49 @@ TEST(ContentSettingsPatternTest, FromURL) {
EXPECT_EQ("file:///foo/bar.html", pattern.ToString());
}
+TEST(ContentSettingsPatternTest, FilesystemUrls) {
+ ContentSettingsPattern pattern =
+ ContentSettingsPattern::FromURL(GURL("http://www.google.com"));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:http://www.google.com/temporary/")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:http://foo.www.google.com/temporary/")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:http://www.google.com:80/temporary/")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:http://www.google.com:81/temporary/")));
+
+ pattern = ContentSettingsPattern::FromURL(GURL("https://www.google.com"));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:https://www.google.com/temporary/")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:https://www.google.com:443/temporary/")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:https://foo.www.google.com/temporary/")));
+ EXPECT_FALSE(pattern.Matches(
+ GURL("filesystem:https://www.google.com:81/temporary/")));
+
+ // A pattern from a filesystem URLs is equivalent to a pattern from the inner
+ // URL of the filesystem URL.
+ ContentSettingsPattern pattern2 = ContentSettingsPattern::FromURL(
+ GURL("filesystem:https://www.google.com/temporary/"));
+ EXPECT_EQ(ContentSettingsPattern::IDENTITY, pattern.Compare(pattern2));
+
+ EXPECT_STREQ("https://[*.]www.google.com:443", pattern2.ToString().c_str());
+
+ pattern =
+ ContentSettingsPattern::FromURL(
+ GURL("filesystem:file:///temporary/foo/bar"));
+ EXPECT_TRUE(pattern.Matches(GURL("filesystem:file:///temporary/")));
+ EXPECT_TRUE(pattern.Matches(GURL("filesystem:file:///temporary/test.txt")));
+ EXPECT_TRUE(pattern.Matches(GURL("file:///temporary")));
+ EXPECT_FALSE(pattern.Matches(GURL("file://foo/bar")));
+ pattern2 =
+ ContentSettingsPattern::FromURL(
+ GURL("filesystem:file:///persistent/foo2/bar2"));
+ EXPECT_EQ(ContentSettingsPattern::IDENTITY, pattern.Compare(pattern2));
+}
+
TEST(ContentSettingsPatternTest, FromURLNoWildcard) {
// If no port is specifed GURLs always use the default port for the schemes
// HTTP and HTTPS. Hence a GURL always carries a port specification either
@@ -114,8 +158,21 @@ TEST(ContentSettingsPatternTest, FromURLNoWildcard) {
EXPECT_TRUE(pattern.Matches(GURL("https://www.example.com")));
EXPECT_FALSE(pattern.Matches(GURL("http://foo.www.example.com")));
- pattern = ContentSettingsPattern::FromURLNoWildcard(
- GURL("https://www.example.com"));
+ // Pattern for filesystem URLs
+ pattern =
+ ContentSettingsPattern::FromURLNoWildcard(
+ GURL("filesystem:http://www.google.com/temporary/"));
+ EXPECT_TRUE(pattern.IsValid());
+ EXPECT_TRUE(pattern.Matches(GURL("http://www.google.com")));
+ EXPECT_FALSE(pattern.Matches(GURL("http://foo.www.google.com")));
+ EXPECT_TRUE(pattern.Matches(
+ GURL("filesystem:http://www.google.com/persistent/")));
+ EXPECT_FALSE(pattern.Matches(
+ GURL("filesystem:https://www.google.com/persistent/")));
+ EXPECT_FALSE(pattern.Matches(
+ GURL("filesystem:https://www.google.com:81/temporary/")));
+ EXPECT_FALSE(pattern.Matches(
+ GURL("filesystem:https://foo.www.google.com/temporary/")));
}
TEST(ContentSettingsPatternTest, Wildcard) {
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index a57b8e1..d5d2e1e 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -2326,16 +2326,27 @@ FileBrowserHandler* Extension::LoadFileBrowserHandler(
return NULL;
}
StringToLowerASCII(&filter);
- URLPattern pattern(URLPattern::SCHEME_FILESYSTEM);
+ if (!StartsWithASCII(filter,
+ std::string(chrome::kFileSystemScheme) + ':',
+ true)) {
+ *error = ExtensionErrorUtils::FormatErrorMessageUTF16(
+ errors::kInvalidURLPatternError, filter);
+ return NULL;
+ }
+ // The user inputs filesystem:*; we don't actually implement scheme
+ // wildcards in URLPattern, so transform to what will match correctly.
+ filter.replace(0, 11, "chrome-extension://*/");
+ URLPattern pattern(URLPattern::SCHEME_EXTENSION);
+ pattern.set_partial_filesystem_support_hack(true);
if (pattern.Parse(filter) != URLPattern::PARSE_SUCCESS) {
*error = ExtensionErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidURLPatternError, filter);
return NULL;
}
std::string path = pattern.path();
- bool allowed = path == "*" || path == "*.*" ||
- (path.compare(0, 2, "*.") == 0 &&
- path.find_first_of('*', 2) == std::string::npos);
+ bool allowed = path == "/*" || path == "/*.*" ||
+ (path.compare(0, 3, "/*.") == 0 &&
+ path.find_first_of('*', 3) == std::string::npos);
if (!allowed) {
*error = ExtensionErrorUtils::FormatErrorMessageUTF16(
errors::kInvalidURLPatternError, filter);
diff --git a/chrome/common/extensions/extension_manifests_unittest.cc b/chrome/common/extensions/extension_manifests_unittest.cc
index 94fd1cd..7cfd038 100644
--- a/chrome/common/extensions/extension_manifests_unittest.cc
+++ b/chrome/common/extensions/extension_manifests_unittest.cc
@@ -1004,6 +1004,7 @@ TEST_F(ExtensionManifestTest, FileBrowserHandlers) {
scoped_refptr<Extension> extension(
LoadAndExpectSuccess("filebrowser_valid.json"));
+ ASSERT_TRUE(extension.get());
ASSERT_TRUE(extension->file_browser_handlers() != NULL);
ASSERT_EQ(extension->file_browser_handlers()->size(), 1U);
const FileBrowserHandler* action =
diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc
index ac64811..c0b04b7 100644
--- a/chrome/common/extensions/url_pattern.cc
+++ b/chrome/common/extensions/url_pattern.cc
@@ -97,12 +97,14 @@ bool IsValidPortForScheme(const std::string scheme, const std::string& port) {
URLPattern::URLPattern()
: valid_schemes_(SCHEME_NONE),
match_all_urls_(false),
+ partial_filesystem_support_hack_(false),
match_subdomains_(false),
port_("*") {}
URLPattern::URLPattern(int valid_schemes)
: valid_schemes_(valid_schemes),
match_all_urls_(false),
+ partial_filesystem_support_hack_(false),
match_subdomains_(false),
port_("*") {}
@@ -111,6 +113,7 @@ URLPattern::URLPattern(int valid_schemes, const std::string& pattern)
// appropriate when we know |pattern| is valid.
: valid_schemes_(valid_schemes),
match_all_urls_(false),
+ partial_filesystem_support_hack_(false),
match_subdomains_(false),
port_("*") {
if (PARSE_SUCCESS != Parse(pattern))
@@ -295,14 +298,27 @@ bool URLPattern::SetPort(const std::string& port) {
}
bool URLPattern::MatchesURL(const GURL& test) const {
- if (!MatchesScheme(test.scheme()))
+ const GURL* test_url = &test;
+ bool has_inner_url = test.inner_url() != NULL;
+
+ if (partial_filesystem_support_hack_ != has_inner_url)
+ return false;
+
+ if (has_inner_url)
+ test_url = test.inner_url();
+
+ if (!MatchesScheme(test_url->scheme()))
return false;
if (match_all_urls_)
return true;
- return MatchesSecurityOriginHelper(test) &&
- MatchesPath(test.PathForRequest());
+ std::string path_for_request = test.PathForRequest();
+ if (has_inner_url)
+ path_for_request = test_url->path() + path_for_request;
+
+ return MatchesSecurityOriginHelper(*test_url) &&
+ MatchesPath(path_for_request);
}
bool URLPattern::MatchesSecurityOrigin(const GURL& test) const {
@@ -433,6 +449,10 @@ bool URLPattern::OverlapsWith(const URLPattern& other) const {
DCHECK(path_.find('*') == path_.size() - 1);
DCHECK(other.path().find('*') == other.path().size() - 1);
+ if (partial_filesystem_support_hack_ !=
+ other.partial_filesystem_support_hack())
+ return false;
+
if (!MatchesPath(other.path().substr(0, other.path().size() - 1)) &&
!other.MatchesPath(path_.substr(0, path_.size() - 1)))
return false;
diff --git a/chrome/common/extensions/url_pattern.h b/chrome/common/extensions/url_pattern.h
index 6a83c01..3cde957 100644
--- a/chrome/common/extensions/url_pattern.h
+++ b/chrome/common/extensions/url_pattern.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 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_COMMON_EXTENSIONS_URL_PATTERN_H_
@@ -119,6 +119,15 @@ class URLPattern {
bool match_all_urls() const { return match_all_urls_; }
void SetMatchAllURLs(bool val);
+ // Returns true if this pattern matches inner URLs of filesystem: URLs only.
+ // Returns false if this pattern matches only non-filesystem URLs.
+ bool partial_filesystem_support_hack() const {
+ return partial_filesystem_support_hack_;
+ }
+ void set_partial_filesystem_support_hack(bool val) {
+ partial_filesystem_support_hack_ = val;
+ }
+
// Sets the scheme for pattern matches. This can be a single '*' if the
// pattern matches all valid schemes (as defined by the valid_schemes_
// property). Returns false on failure (if the scheme is not valid).
@@ -204,6 +213,11 @@ class URLPattern {
// True if this is a special-case "<all_urls>" pattern.
bool match_all_urls_;
+ // True if we're trying to match against the inner URL of a filesystem URL;
+ // this is a temporary hack so as not to break ChromeOS as we work on full
+ // support.
+ bool partial_filesystem_support_hack_;
+
// The scheme for the pattern.
std::string scheme_;
diff --git a/chrome/common/extensions/url_pattern_unittest.cc b/chrome/common/extensions/url_pattern_unittest.cc
index 3996b99..10dff3d 100644
--- a/chrome/common/extensions/url_pattern_unittest.cc
+++ b/chrome/common/extensions/url_pattern_unittest.cc
@@ -110,6 +110,11 @@ TEST(ExtensionURLPatternTest, Match2) {
EXPECT_TRUE(pattern.MatchesURL(GURL("https://www.google.com/foobar")));
EXPECT_FALSE(pattern.MatchesURL(GURL("http://www.google.com/foo")));
EXPECT_FALSE(pattern.MatchesURL(GURL("https://www.google.com/")));
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:https://www.google.com/foobar/")));
+ pattern.set_partial_filesystem_support_hack(true);
+ EXPECT_TRUE(pattern.MatchesURL(
+ GURL("filesystem:https://www.google.com/foobar/bas")));
}
// subdomains
@@ -127,6 +132,11 @@ TEST(URLPatternTest, Match3) {
EXPECT_TRUE(pattern.MatchesURL(
GURL("http://monkey.images.google.com/foooobar")));
EXPECT_FALSE(pattern.MatchesURL(GURL("http://yahoo.com/foobar")));
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:http://google.com/foobar/")));
+ pattern.set_partial_filesystem_support_hack(true);
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:http://google.com/temporary/foobar")));
}
// glob escaping
@@ -226,6 +236,7 @@ TEST(ExtensionURLPatternTest, Match11) {
EXPECT_TRUE(pattern.MatchesScheme("http"));
EXPECT_TRUE(pattern.MatchesScheme("https"));
EXPECT_TRUE(pattern.MatchesScheme("file"));
+ EXPECT_TRUE(pattern.MatchesScheme("filesystem"));
EXPECT_TRUE(pattern.MatchesScheme("chrome-extension"));
EXPECT_TRUE(pattern.match_subdomains());
EXPECT_TRUE(pattern.match_all_urls());
@@ -257,6 +268,7 @@ TEST(ExtensionURLPatternTest, Match12) {
EXPECT_TRUE(pattern.MatchesScheme("http"));
EXPECT_TRUE(pattern.MatchesScheme("https"));
EXPECT_TRUE(pattern.MatchesScheme("file"));
+ EXPECT_TRUE(pattern.MatchesScheme("filesystem"));
EXPECT_TRUE(pattern.MatchesScheme("javascript"));
EXPECT_TRUE(pattern.MatchesScheme("data"));
EXPECT_TRUE(pattern.MatchesScheme("about"));
@@ -368,6 +380,11 @@ TEST(ExtensionURLPatternTest, Match17) {
EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:80/foo")));
EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com/foo")));
EXPECT_FALSE(pattern.MatchesURL(GURL("http://www.example.com:8080/foo")));
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:http://www.example.com:8080/foo/")));
+ EXPECT_FALSE(pattern.MatchesURL(GURL("filesystem:http://www.example.com/f/foo")));
+ pattern.set_partial_filesystem_support_hack(true);
+ EXPECT_FALSE(pattern.MatchesURL(GURL("filesystem:http://www.example.com/f/foo")));
}
// Explicit port wildcard
@@ -384,6 +401,8 @@ TEST(ExtensionURLPatternTest, Match18) {
EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:80/foo")));
EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com/foo")));
EXPECT_TRUE(pattern.MatchesURL(GURL("http://www.example.com:8080/foo")));
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:http://www.example.com:8080/foo/")));
}
// chrome-extension://
@@ -402,6 +421,11 @@ TEST(ExtensionURLPatternTest, Match19) {
EXPECT_TRUE(pattern.MatchesURL(
GURL("chrome-extension://ftw/https://google.com")));
EXPECT_FALSE(pattern.MatchesURL(GURL("chrome-extension://foobar")));
+ EXPECT_FALSE(pattern.MatchesURL(
+ GURL("filesystem:chrome-extension://ftw/t/file.txt")));
+ pattern.set_partial_filesystem_support_hack(true);
+ EXPECT_TRUE(pattern.MatchesURL(
+ GURL("filesystem:chrome-extension://ftw/t/file.txt")));
};
static const struct GetAsStringPatterns {