Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6906)

Unified Diff: chrome/common/extensions/url_pattern.cc

Issue 7811006: Add full support for filesystem URLs. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added TODO for markusheintz Created 8 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/common/extensions/url_pattern.cc
diff --git a/chrome/common/extensions/url_pattern.cc b/chrome/common/extensions/url_pattern.cc
index ac648114aaed54e93ec873b92dbd71afe384ae42..a224d38d811d96ec2b17d34657cb8ad3ba8edcb9 100644
--- a/chrome/common/extensions/url_pattern.cc
+++ b/chrome/common/extensions/url_pattern.cc
@@ -96,12 +96,14 @@ bool IsValidPortForScheme(const std::string scheme, const std::string& port) {
URLPattern::URLPattern()
: valid_schemes_(SCHEME_NONE),
+ valid_inner_schemes_(SCHEME_NONE),
match_all_urls_(false),
match_subdomains_(false),
port_("*") {}
URLPattern::URLPattern(int valid_schemes)
: valid_schemes_(valid_schemes),
+ valid_inner_schemes_(valid_schemes),
match_all_urls_(false),
match_subdomains_(false),
port_("*") {}
@@ -110,6 +112,7 @@ URLPattern::URLPattern(int valid_schemes, const std::string& pattern)
// Strict error checking is used, because this constructor is only
// appropriate when we know |pattern| is valid.
: valid_schemes_(valid_schemes),
+ valid_inner_schemes_(valid_schemes),
match_all_urls_(false),
match_subdomains_(false),
port_("*") {
@@ -141,28 +144,43 @@ URLPattern::ParseResult URLPattern::Parse(const std::string& pattern) {
}
// Parse out the scheme.
- size_t scheme_end_pos = pattern.find(chrome::kStandardSchemeSeparator);
- bool has_standard_scheme_separator = true;
-
- // Some urls also use ':' alone as the scheme separator.
- if (scheme_end_pos == std::string::npos) {
- scheme_end_pos = pattern.find(':');
- has_standard_scheme_separator = false;
- }
-
+ size_t scheme_end_pos = pattern.find(':');
if (scheme_end_pos == std::string::npos)
return PARSE_ERROR_MISSING_SCHEME_SEPARATOR;
+ bool has_standard_scheme_separator = false;
+ if (scheme_end_pos + 2 < pattern.length() &&
+ pattern[scheme_end_pos + 1] == '/' &&
+ pattern[scheme_end_pos + 2] == '/') {
+ has_standard_scheme_separator = true;
+ }
+
if (!SetScheme(pattern.substr(0, scheme_end_pos)))
return PARSE_ERROR_INVALID_SCHEME;
bool standard_scheme = IsStandardScheme(scheme_);
+
+ if (scheme_ == chrome::kFileSystemScheme) {
Aaron Boodman 2012/03/12 23:17:13 Yeah, would prefer this was something like if (Sup
ericu 2012/03/13 21:58:47 Done.
+ size_t inner_scheme_start_pos = scheme_end_pos + 1;
+ scheme_end_pos = pattern.find(chrome::kStandardSchemeSeparator,
+ inner_scheme_start_pos);
+ if (scheme_end_pos == std::string::npos)
+ return PARSE_ERROR_MISSING_SCHEME_SEPARATOR;
+ has_standard_scheme_separator = true;
+ if (!SetInnerScheme(
+ pattern.substr(inner_scheme_start_pos,
+ scheme_end_pos - inner_scheme_start_pos)))
+ return PARSE_ERROR_INVALID_SCHEME;
Aaron Boodman 2012/03/12 23:17:13 PARSE_ERROR_INVALID_INNER_SCHEME seems better here
ericu 2012/03/13 21:58:47 Done.
+ standard_scheme = IsStandardScheme(inner_scheme_);
+ }
+
if (standard_scheme != has_standard_scheme_separator)
Aaron Boodman 2012/03/12 23:17:13 I still think this method has gotten too long and
ericu 2012/03/13 21:58:47 Done.
return PARSE_ERROR_WRONG_SCHEME_SEPARATOR;
// Advance past the scheme separator.
scheme_end_pos +=
- (standard_scheme ? strlen(chrome::kStandardSchemeSeparator) : 1);
+ (has_standard_scheme_separator ?
+ strlen(chrome::kStandardSchemeSeparator) : 1);
if (scheme_end_pos >= pattern.size())
return PARSE_ERROR_EMPTY_HOST;
@@ -184,6 +202,11 @@ URLPattern::ParseResult URLPattern::Parse(const std::string& pattern) {
// e.g. file://localhost/foo is equal to file:///foo.
path_start_pos = host_end_pos;
}
+ } else if (scheme_ == chrome::kFileSystemScheme &&
+ inner_scheme_ == chrome::kFileScheme) {
+ // We can't distinguish between a host and a storage type in a
+ // filesystem:file URL, so just let it be part of the path.
+ path_start_pos = host_start_pos;
} else {
size_t host_end_pos = pattern.find(kPathSeparator, host_start_pos);
@@ -230,6 +253,12 @@ URLPattern::ParseResult URLPattern::Parse(const std::string& pattern) {
void URLPattern::SetValidSchemes(int valid_schemes) {
spec_.clear();
valid_schemes_ = valid_schemes;
+ valid_inner_schemes_ = valid_schemes;
+}
+
+void URLPattern::SetValidInnerSchemes(int valid_schemes) {
+ spec_.clear();
+ valid_inner_schemes_ = valid_schemes;
}
void URLPattern::SetHost(const std::string& host) {
@@ -256,12 +285,26 @@ void URLPattern::SetMatchSubdomains(bool val) {
bool URLPattern::SetScheme(const std::string& scheme) {
spec_.clear();
- scheme_ = scheme;
- if (scheme_ == "*") {
+ inner_scheme_.clear();
+ if (scheme == "*") {
valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS);
- } else if (!IsValidScheme(scheme_)) {
+ } else if (!IsValidScheme(scheme)) {
+ return false;
+ }
+ scheme_ = scheme;
+ return true;
+}
+
+bool URLPattern::SetInnerScheme(const std::string& inner_scheme) {
+ spec_.clear();
+ DCHECK(scheme_ == chrome::kFileSystemScheme);
+ if (inner_scheme == "*") {
+ valid_inner_schemes_ = SCHEME_HTTP | SCHEME_HTTPS | SCHEME_FTP |
Aaron Boodman 2012/03/12 23:17:13 I am not sure why SetScheme modifies the valid sch
Aaron Boodman 2012/03/12 23:17:13 Why this particular interpretation of "*"? Note th
ericu 2012/03/13 21:58:47 I implemented it based on the comment in url_patte
ericu 2012/03/13 21:58:47 I'm OK with changing the behavior--there aren't al
+ SCHEME_EXTENSION; // Exclude file: and chrome:.
+ } else if (!IsValidInnerScheme(inner_scheme)) {
return false;
}
+ inner_scheme_ = inner_scheme;
return true;
}
@@ -277,6 +320,23 @@ bool URLPattern::IsValidScheme(const std::string& scheme) const {
return false;
}
+bool URLPattern::IsValidInnerScheme(const std::string& scheme) const {
+ // kFileSystemScheme is never a valid inner scheme, even if using SCHEME_ALL.
+ if (scheme == chrome::kFileSystemScheme)
+ return false;
+
+ if (valid_inner_schemes_ == SCHEME_ALL)
+ return true;
+
+ for (size_t i = 0; i < arraysize(kValidSchemes); ++i) {
+ if (scheme == kValidSchemes[i] &&
+ (valid_inner_schemes_ & kValidSchemeMasks[i]))
+ return true;
+ }
+
+ return false;
+}
+
void URLPattern::SetPath(const std::string& path) {
spec_.clear();
path_ = path;
@@ -287,7 +347,9 @@ void URLPattern::SetPath(const std::string& path) {
bool URLPattern::SetPort(const std::string& port) {
spec_.clear();
- if (IsValidPortForScheme(scheme_, port)) {
+ std::string scheme =
+ (scheme_ == chrome::kFileSystemScheme) ? inner_scheme_ : scheme_;
+ if (IsValidPortForScheme(scheme, port)) {
port_ = port;
return true;
}
@@ -301,8 +363,19 @@ bool URLPattern::MatchesURL(const GURL& test) const {
if (match_all_urls_)
return true;
- return MatchesSecurityOriginHelper(test) &&
- MatchesPath(test.PathForRequest());
+ DCHECK(!test.SchemeIsFileSystem() || test.inner_url());
+ if (scheme_ == chrome::kFileSystemScheme &&
+ (!test.SchemeIsFileSystem() ||
+ !MatchesInnerScheme(test.inner_url()->scheme())))
Aaron Boodman 2012/03/12 23:17:13 Style guide requires curly braces here.
ericu 2012/03/13 21:58:47 Done.
+ return false;
+
+ std::string path = test.PathForRequest();
+
+ // Filesystem URLs have the first path segment on the inner_url.
+ if (test.SchemeIsFileSystem())
+ path = test.inner_url()->path() + path;
+
+ return MatchesSecurityOriginHelper(test) && MatchesPath(path);
}
bool URLPattern::MatchesSecurityOrigin(const GURL& test) const {
@@ -322,6 +395,14 @@ bool URLPattern::MatchesScheme(const std::string& test) const {
return scheme_ == "*" || test == scheme_;
}
+bool URLPattern::MatchesInnerScheme(const std::string& test) const {
+ DCHECK(scheme_ == chrome::kFileSystemScheme);
+ if (!IsValidInnerScheme(test))
+ return false;
+
+ return inner_scheme_ == "*" || test == inner_scheme_;
+}
+
bool URLPattern::MatchesHost(const std::string& host) const {
std::string test(chrome::kHttpScheme);
test += chrome::kStandardSchemeSeparator;
@@ -387,10 +468,18 @@ const std::string& URLPattern::GetAsString() const {
bool standard_scheme = IsStandardScheme(scheme_);
Aaron Boodman 2012/03/12 23:17:13 Can you rename this to 'is_standard_scheme' while
ericu 2012/03/13 21:58:47 Done.
- std::string spec = scheme_ +
- (standard_scheme ? chrome::kStandardSchemeSeparator : ":");
+ std::string spec = scheme_;
+ std::string scheme = scheme_;
+ bool add_standard_separator = standard_scheme;
+ if (scheme_ == chrome::kFileSystemScheme) {
+ spec += ":" + inner_scheme_;
+ add_standard_separator = true;
+ standard_scheme = IsStandardScheme(inner_scheme_);
+ scheme = inner_scheme_;
+ }
+ spec += (add_standard_separator ? chrome::kStandardSchemeSeparator : ":");
- if (scheme_ != chrome::kFileScheme && standard_scheme) {
+ if (scheme != chrome::kFileScheme && standard_scheme) {
if (match_subdomains_) {
spec += "*";
if (!host_.empty())
@@ -452,11 +541,18 @@ bool URLPattern::MatchesAnyScheme(
}
bool URLPattern::MatchesSecurityOriginHelper(const GURL& test) const {
- // Ignore hostname if scheme is file://.
- if (scheme_ != chrome::kFileScheme && !MatchesHost(test))
+ // Ignore hostname if scheme is file:// or filesystem:file://.
+ std::string scheme = scheme_;
+ const GURL* test_url = &test;
+ if (scheme == chrome::kFileSystemScheme) {
+ scheme = inner_scheme_;
+ test_url = test.inner_url();
+ DCHECK(test_url);
+ }
+ if (scheme != chrome::kFileScheme && !MatchesHost(*test_url))
return false;
- if (!MatchesPort(test.EffectiveIntPort()))
+ if (!MatchesPort(test_url->EffectiveIntPort()))
return false;
return true;

Powered by Google App Engine
This is Rietveld 408576698