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

Side by Side 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: Merged out Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/common/extensions/url_pattern.h" 5 #include "chrome/common/extensions/url_pattern.h"
6 6
7 #include "base/string_number_conversions.h" 7 #include "base/string_number_conversions.h"
8 #include "base/string_piece.h" 8 #include "base/string_piece.h"
9 #include "base/string_split.h" 9 #include "base/string_split.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
60 kParseErrorInvalidHostWildcard, 60 kParseErrorInvalidHostWildcard,
61 kParseErrorEmptyPath, 61 kParseErrorEmptyPath,
62 kParseErrorInvalidPort, 62 kParseErrorInvalidPort,
63 }; 63 };
64 64
65 COMPILE_ASSERT(URLPattern::NUM_PARSE_RESULTS == arraysize(kParseResultMessages), 65 COMPILE_ASSERT(URLPattern::NUM_PARSE_RESULTS == arraysize(kParseResultMessages),
66 must_add_message_for_each_parse_result); 66 must_add_message_for_each_parse_result);
67 67
68 const char kPathSeparator[] = "/"; 68 const char kPathSeparator[] = "/";
69 69
70 bool IsStandardScheme(const std::string& scheme) { 70 bool is_standard_scheme(const std::string& scheme) {
Aaron Boodman 2012/03/21 23:51:57 Why rename this? I think the current capitalizatio
ericu 2012/03/22 00:22:14 You requested this change in your comments on patc
71 // "*" gets the same treatment as a standard scheme. 71 // "*" gets the same treatment as a standard scheme.
72 if (scheme == "*") 72 if (scheme == "*")
73 return true; 73 return true;
74 74
75 return url_util::IsStandard(scheme.c_str(), 75 return url_util::IsStandard(scheme.c_str(),
76 url_parse::Component(0, static_cast<int>(scheme.length()))); 76 url_parse::Component(0, static_cast<int>(scheme.length())));
77 } 77 }
78 78
79 bool IsValidPortForScheme(const std::string scheme, const std::string& port) { 79 bool IsValidPortForScheme(const std::string scheme, const std::string& port) {
80 if (port == "*") 80 if (port == "*")
81 return true; 81 return true;
82 82
83 // Only accept non-wildcard ports if the scheme uses ports. 83 // Only accept non-wildcard ports if the scheme uses ports.
84 if (url_canon::DefaultPortForScheme(scheme.c_str(), scheme.length()) == 84 if (url_canon::DefaultPortForScheme(scheme.c_str(), scheme.length()) ==
85 url_parse::PORT_UNSPECIFIED) { 85 url_parse::PORT_UNSPECIFIED) {
86 return false; 86 return false;
87 } 87 }
88 88
89 int parsed_port = url_parse::PORT_UNSPECIFIED; 89 int parsed_port = url_parse::PORT_UNSPECIFIED;
90 if (!base::StringToInt(port, &parsed_port)) 90 if (!base::StringToInt(port, &parsed_port))
91 return false; 91 return false;
92 return (parsed_port >= 0) && (parsed_port < 65536); 92 return (parsed_port >= 0) && (parsed_port < 65536);
93 } 93 }
94 94
95 } // namespace 95 } // namespace
96 96
97 URLPattern::URLPattern() 97 URLPattern::URLPattern()
98 : valid_schemes_(SCHEME_NONE), 98 : valid_schemes_(SCHEME_NONE),
99 match_all_urls_(false), 99 match_all_urls_(false),
100 match_nested_url_path_(false),
100 match_subdomains_(false), 101 match_subdomains_(false),
101 port_("*") {} 102 port_("*") {}
102 103
103 URLPattern::URLPattern(int valid_schemes) 104 URLPattern::URLPattern(int valid_schemes)
104 : valid_schemes_(valid_schemes), 105 : valid_schemes_(valid_schemes),
105 match_all_urls_(false), 106 match_all_urls_(false),
107 match_nested_url_path_(false),
106 match_subdomains_(false), 108 match_subdomains_(false),
107 port_("*") {} 109 port_("*") {}
108 110
109 URLPattern::URLPattern(int valid_schemes, const std::string& pattern) 111 URLPattern::URLPattern(int valid_schemes, const std::string& pattern)
110 // Strict error checking is used, because this constructor is only 112 // Strict error checking is used, because this constructor is only
111 // appropriate when we know |pattern| is valid. 113 // appropriate when we know |pattern| is valid.
112 : valid_schemes_(valid_schemes), 114 : valid_schemes_(valid_schemes),
113 match_all_urls_(false), 115 match_all_urls_(false),
116 match_nested_url_path_(false),
114 match_subdomains_(false), 117 match_subdomains_(false),
115 port_("*") { 118 port_("*") {
116 if (PARSE_SUCCESS != Parse(pattern)) 119 if (PARSE_SUCCESS != Parse(pattern))
117 NOTREACHED() << "URLPattern is invalid: " << pattern; 120 NOTREACHED() << "URLPattern is invalid: " << pattern;
118 } 121 }
119 122
120 URLPattern::~URLPattern() { 123 URLPattern::~URLPattern() {
121 } 124 }
122 125
123 bool URLPattern::operator<(const URLPattern& other) const { 126 bool URLPattern::operator<(const URLPattern& other) const {
(...skipping 25 matching lines...) Expand all
149 scheme_end_pos = pattern.find(':'); 152 scheme_end_pos = pattern.find(':');
150 has_standard_scheme_separator = false; 153 has_standard_scheme_separator = false;
151 } 154 }
152 155
153 if (scheme_end_pos == std::string::npos) 156 if (scheme_end_pos == std::string::npos)
154 return PARSE_ERROR_MISSING_SCHEME_SEPARATOR; 157 return PARSE_ERROR_MISSING_SCHEME_SEPARATOR;
155 158
156 if (!SetScheme(pattern.substr(0, scheme_end_pos))) 159 if (!SetScheme(pattern.substr(0, scheme_end_pos)))
157 return PARSE_ERROR_INVALID_SCHEME; 160 return PARSE_ERROR_INVALID_SCHEME;
158 161
159 bool standard_scheme = IsStandardScheme(scheme_); 162 bool standard_scheme = is_standard_scheme(scheme_);
160 if (standard_scheme != has_standard_scheme_separator) 163 if (standard_scheme != has_standard_scheme_separator)
161 return PARSE_ERROR_WRONG_SCHEME_SEPARATOR; 164 return PARSE_ERROR_WRONG_SCHEME_SEPARATOR;
162 165
163 // Advance past the scheme separator. 166 // Advance past the scheme separator.
164 scheme_end_pos += 167 scheme_end_pos +=
165 (standard_scheme ? strlen(chrome::kStandardSchemeSeparator) : 1); 168 (standard_scheme ? strlen(chrome::kStandardSchemeSeparator) : 1);
166 if (scheme_end_pos >= pattern.size()) 169 if (scheme_end_pos >= pattern.size())
167 return PARSE_ERROR_EMPTY_HOST; 170 return PARSE_ERROR_EMPTY_HOST;
168 171
169 // Parse out the host and path. 172 // Parse out the host and path.
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 match_all_urls_ = val; 245 match_all_urls_ = val;
243 246
244 if (val) { 247 if (val) {
245 match_subdomains_ = true; 248 match_subdomains_ = true;
246 scheme_ = "*"; 249 scheme_ = "*";
247 host_.clear(); 250 host_.clear();
248 SetPath("/*"); 251 SetPath("/*");
249 } 252 }
250 } 253 }
251 254
255 void URLPattern::SetMatchNestedURLPath(bool val) {
Aaron Boodman 2012/03/21 23:51:57 This one on the other hand should be set_match_nes
ericu 2012/03/22 00:22:14 Done.
256 match_nested_url_path_ = val;
257 }
258
252 void URLPattern::SetMatchSubdomains(bool val) { 259 void URLPattern::SetMatchSubdomains(bool val) {
253 spec_.clear(); 260 spec_.clear();
254 match_subdomains_ = val; 261 match_subdomains_ = val;
255 } 262 }
256 263
257 bool URLPattern::SetScheme(const std::string& scheme) { 264 bool URLPattern::SetScheme(const std::string& scheme) {
258 spec_.clear(); 265 spec_.clear();
259 scheme_ = scheme; 266 scheme_ = scheme;
260 if (scheme_ == "*") { 267 if (scheme_ == "*") {
261 valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS); 268 valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS);
(...skipping 26 matching lines...) Expand all
288 bool URLPattern::SetPort(const std::string& port) { 295 bool URLPattern::SetPort(const std::string& port) {
289 spec_.clear(); 296 spec_.clear();
290 if (IsValidPortForScheme(scheme_, port)) { 297 if (IsValidPortForScheme(scheme_, port)) {
291 port_ = port; 298 port_ = port;
292 return true; 299 return true;
293 } 300 }
294 return false; 301 return false;
295 } 302 }
296 303
297 bool URLPattern::MatchesURL(const GURL& test) const { 304 bool URLPattern::MatchesURL(const GURL& test) const {
298 if (!MatchesScheme(test.scheme())) 305 const GURL* test_url = &test;
306 bool has_inner_url = false;
307 if (test.inner_url()) {
308 test_url = test.inner_url();
309 has_inner_url = true;
310 }
311
312 if (!MatchesScheme(test_url->scheme()))
299 return false; 313 return false;
300 314
301 if (match_all_urls_) 315 if (match_all_urls_)
302 return true; 316 return true;
303 317
304 return MatchesSecurityOriginHelper(test) && 318 std::string path_for_request = test.PathForRequest();
305 MatchesPath(test.PathForRequest()); 319 if (has_inner_url) {
320 path_for_request = test_url->path() + path_for_request;
321 }
322 return MatchesSecurityOriginHelper(*test_url) &&
323 MatchesPath(path_for_request, has_inner_url);
306 } 324 }
307 325
308 bool URLPattern::MatchesSecurityOrigin(const GURL& test) const { 326 bool URLPattern::MatchesSecurityOrigin(const GURL& test) const {
309 if (!MatchesScheme(test.scheme())) 327 if (!MatchesScheme(test.scheme()))
310 return false; 328 return false;
311 329
312 if (match_all_urls_) 330 if (match_all_urls_)
313 return true; 331 return true;
314 332
315 return MatchesSecurityOriginHelper(test); 333 return MatchesSecurityOriginHelper(test);
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
354 if (test.host().length() <= (host_.length() + 1)) 372 if (test.host().length() <= (host_.length() + 1))
355 return false; 373 return false;
356 374
357 if (test.host().compare(test.host().length() - host_.length(), 375 if (test.host().compare(test.host().length() - host_.length(),
358 host_.length(), host_) != 0) 376 host_.length(), host_) != 0)
359 return false; 377 return false;
360 378
361 return test.host()[test.host().length() - host_.length() - 1] == '.'; 379 return test.host()[test.host().length() - host_.length() - 1] == '.';
362 } 380 }
363 381
364 bool URLPattern::MatchesPath(const std::string& test) const { 382 bool URLPattern::MatchesPath(const std::string& test, bool nested_url)
383 const {
384 if (nested_url != match_nested_url_path_ && path_ != "/*")
385 return false;
365 if (!MatchPattern(test, path_escaped_)) 386 if (!MatchPattern(test, path_escaped_))
366 return false; 387 return false;
367 388
368 return true; 389 return true;
369 } 390 }
370 391
371 bool URLPattern::MatchesPort(int port) const { 392 bool URLPattern::MatchesPort(int port) const {
372 if (port == url_parse::PORT_INVALID) 393 if (port == url_parse::PORT_INVALID)
373 return false; 394 return false;
374 395
375 return port_ == "*" || port_ == base::IntToString(port); 396 return port_ == "*" || port_ == base::IntToString(port);
376 } 397 }
377 398
378 399
379 const std::string& URLPattern::GetAsString() const { 400 const std::string& URLPattern::GetAsString() const {
380 if (!spec_.empty()) 401 if (!spec_.empty())
381 return spec_; 402 return spec_;
382 403
383 if (match_all_urls_) { 404 if (match_all_urls_) {
384 spec_ = kAllUrlsPattern; 405 spec_ = kAllUrlsPattern;
385 return spec_; 406 return spec_;
386 } 407 }
387 408
388 bool standard_scheme = IsStandardScheme(scheme_); 409 bool standard_scheme = is_standard_scheme(scheme_);
389 410
390 std::string spec = scheme_ + 411 std::string spec = scheme_ +
391 (standard_scheme ? chrome::kStandardSchemeSeparator : ":"); 412 (standard_scheme ? chrome::kStandardSchemeSeparator : ":");
392 413
393 if (scheme_ != chrome::kFileScheme && standard_scheme) { 414 if (scheme_ != chrome::kFileScheme && standard_scheme) {
394 if (match_subdomains_) { 415 if (match_subdomains_) {
395 spec += "*"; 416 spec += "*";
396 if (!host_.empty()) 417 if (!host_.empty())
397 spec += "."; 418 spec += ".";
398 } 419 }
(...skipping 27 matching lines...) Expand all
426 return false; 447 return false;
427 448
428 // We currently only use OverlapsWith() for the patterns inside 449 // We currently only use OverlapsWith() for the patterns inside
429 // URLPatternSet. In those cases, we know that the path will have only a 450 // URLPatternSet. In those cases, we know that the path will have only a
430 // single wildcard at the end. This makes figuring out overlap much easier. It 451 // single wildcard at the end. This makes figuring out overlap much easier. It
431 // seems like there is probably a computer-sciency way to solve the general 452 // seems like there is probably a computer-sciency way to solve the general
432 // case, but we don't need that yet. 453 // case, but we don't need that yet.
433 DCHECK(path_.find('*') == path_.size() - 1); 454 DCHECK(path_.find('*') == path_.size() - 1);
434 DCHECK(other.path().find('*') == other.path().size() - 1); 455 DCHECK(other.path().find('*') == other.path().size() - 1);
435 456
436 if (!MatchesPath(other.path().substr(0, other.path().size() - 1)) && 457 if ((path_.size() > 2 || other.path().size() > 2) &&
437 !other.MatchesPath(path_.substr(0, path_.size() - 1))) 458 match_nested_url_path_ != other.match_nested_url_path())
459 return false;
460
461 if (!MatchesPath(other.path().substr(0, other.path().size() - 1),
462 match_nested_url_path_) &&
463 !other.MatchesPath(path_.substr(0, path_.size() - 1),
464 match_nested_url_path_))
438 return false; 465 return false;
439 466
440 return true; 467 return true;
441 } 468 }
442 469
443 bool URLPattern::MatchesAnyScheme( 470 bool URLPattern::MatchesAnyScheme(
444 const std::vector<std::string>& schemes) const { 471 const std::vector<std::string>& schemes) const {
445 for (std::vector<std::string>::const_iterator i = schemes.begin(); 472 for (std::vector<std::string>::const_iterator i = schemes.begin();
446 i != schemes.end(); ++i) { 473 i != schemes.end(); ++i) {
447 if (MatchesScheme(*i)) 474 if (MatchesScheme(*i))
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 } 519 }
493 520
494 return result; 521 return result;
495 } 522 }
496 523
497 // static 524 // static
498 const char* URLPattern::GetParseResultString( 525 const char* URLPattern::GetParseResultString(
499 URLPattern::ParseResult parse_result) { 526 URLPattern::ParseResult parse_result) {
500 return kParseResultMessages[parse_result]; 527 return kParseResultMessages[parse_result];
501 } 528 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698