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

Side by Side Diff: chrome/common/extensions/url_pattern.cc

Issue 7229012: Use extension match pattern syntax in content settings extension API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: review Created 9 years, 6 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_piece.h" 8 #include "base/string_piece.h"
8 #include "base/string_split.h" 9 #include "base/string_split.h"
9 #include "base/string_util.h" 10 #include "base/string_util.h"
10 #include "chrome/common/url_constants.h" 11 #include "chrome/common/url_constants.h"
11 #include "googleurl/src/gurl.h" 12 #include "googleurl/src/gurl.h"
12 #include "googleurl/src/url_util.h" 13 #include "googleurl/src/url_util.h"
13 14
14 const char URLPattern::kAllUrlsPattern[] = "<all_urls>"; 15 const char URLPattern::kAllUrlsPattern[] = "<all_urls>";
15 16
16 namespace { 17 namespace {
(...skipping 24 matching lines...) Expand all
41 42
42 const char* kParseSuccess = "Success."; 43 const char* kParseSuccess = "Success.";
43 const char* kParseErrorMissingSchemeSeparator = "Missing scheme separator."; 44 const char* kParseErrorMissingSchemeSeparator = "Missing scheme separator.";
44 const char* kParseErrorInvalidScheme = "Invalid scheme."; 45 const char* kParseErrorInvalidScheme = "Invalid scheme.";
45 const char* kParseErrorWrongSchemeType = "Wrong scheme type."; 46 const char* kParseErrorWrongSchemeType = "Wrong scheme type.";
46 const char* kParseErrorEmptyHost = "Host can not be empty."; 47 const char* kParseErrorEmptyHost = "Host can not be empty.";
47 const char* kParseErrorInvalidHostWildcard = "Invalid host wildcard."; 48 const char* kParseErrorInvalidHostWildcard = "Invalid host wildcard.";
48 const char* kParseErrorEmptyPath = "Empty path."; 49 const char* kParseErrorEmptyPath = "Empty path.";
49 const char* kParseErrorHasColon = 50 const char* kParseErrorHasColon =
50 "Ports are not supported in URL patterns. ':' may not be used in a host."; 51 "Ports are not supported in URL patterns. ':' may not be used in a host.";
52 const char* kParseErrorInvalidPort =
53 "Invalid port.";
51 54
52 // Message explaining each URLPattern::ParseResult. 55 // Message explaining each URLPattern::ParseResult.
53 const char* kParseResultMessages[] = { 56 const char* kParseResultMessages[] = {
54 kParseSuccess, 57 kParseSuccess,
55 kParseErrorMissingSchemeSeparator, 58 kParseErrorMissingSchemeSeparator,
56 kParseErrorInvalidScheme, 59 kParseErrorInvalidScheme,
57 kParseErrorWrongSchemeType, 60 kParseErrorWrongSchemeType,
58 kParseErrorEmptyHost, 61 kParseErrorEmptyHost,
59 kParseErrorInvalidHostWildcard, 62 kParseErrorInvalidHostWildcard,
60 kParseErrorEmptyPath, 63 kParseErrorEmptyPath,
61 kParseErrorHasColon 64 kParseErrorHasColon,
65 kParseErrorInvalidPort,
62 }; 66 };
63 67
64 COMPILE_ASSERT(URLPattern::NUM_PARSE_RESULTS == arraysize(kParseResultMessages), 68 COMPILE_ASSERT(URLPattern::NUM_PARSE_RESULTS == arraysize(kParseResultMessages),
65 must_add_message_for_each_parse_result); 69 must_add_message_for_each_parse_result);
66 70
67 const char kPathSeparator[] = "/"; 71 const char kPathSeparator[] = "/";
68 72
69 bool IsStandardScheme(const std::string& scheme) { 73 bool IsStandardScheme(const std::string& scheme) {
70 // "*" gets the same treatment as a standard scheme. 74 // "*" gets the same treatment as a standard scheme.
71 if (scheme == "*") 75 if (scheme == "*")
72 return true; 76 return true;
73 77
74 return url_util::IsStandard(scheme.c_str(), 78 return url_util::IsStandard(scheme.c_str(),
75 url_parse::Component(0, static_cast<int>(scheme.length()))); 79 url_parse::Component(0, static_cast<int>(scheme.length())));
76 } 80 }
77 81
82 bool IsValidPort(const std::string& port) {
83 if (port.empty() || port == "*")
84 return true;
85 int parsed_port;
86 if (!base::StringToInt(port, &parsed_port))
87 return false;
88 return (parsed_port >= 0) && (parsed_port < 65536);
89 }
90
78 } // namespace 91 } // namespace
79 92
80 URLPattern::URLPattern() 93 URLPattern::URLPattern()
81 : valid_schemes_(SCHEME_NONE), 94 : valid_schemes_(SCHEME_NONE),
82 match_all_urls_(false), 95 match_all_urls_(false),
83 match_subdomains_(false) {} 96 match_subdomains_(false),
97 ignore_ports_(true) {}
84 98
85 URLPattern::URLPattern(int valid_schemes) 99 URLPattern::URLPattern(int valid_schemes)
86 : valid_schemes_(valid_schemes), match_all_urls_(false), 100 : valid_schemes_(valid_schemes),
87 match_subdomains_(false) {} 101 match_all_urls_(false),
102 match_subdomains_(false),
103 ignore_ports_(true) {}
88 104
89 URLPattern::URLPattern(int valid_schemes, const std::string& pattern) 105 URLPattern::URLPattern(int valid_schemes, const std::string& pattern)
90 : valid_schemes_(valid_schemes), match_all_urls_(false), 106 : valid_schemes_(valid_schemes),
91 match_subdomains_(false) { 107 match_all_urls_(false),
108 match_subdomains_(false),
109 ignore_ports_(true) {
92 110
93 // Strict error checking is used, because this constructor is only 111 // Strict error checking is used, because this constructor is only
94 // appropriate when we know |pattern| is valid. 112 // appropriate when we know |pattern| is valid.
95 if (PARSE_SUCCESS != Parse(pattern, PARSE_STRICT)) 113 if (PARSE_SUCCESS != Parse(pattern, PARSE_STRICT))
96 NOTREACHED() << "URLPattern is invalid: " << pattern; 114 NOTREACHED() << "URLPattern is invalid: " << pattern;
97 } 115 }
98 116
99 URLPattern::~URLPattern() { 117 URLPattern::~URLPattern() {
100 } 118 }
101 119
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 // done as a convenience to developers who might otherwise be confused and 202 // done as a convenience to developers who might otherwise be confused and
185 // think '*' works as a glob in the host. 203 // think '*' works as a glob in the host.
186 if (host_.find('*') != std::string::npos) 204 if (host_.find('*') != std::string::npos)
187 return PARSE_ERROR_INVALID_HOST_WILDCARD; 205 return PARSE_ERROR_INVALID_HOST_WILDCARD;
188 206
189 path_start_pos = host_end_pos; 207 path_start_pos = host_end_pos;
190 } 208 }
191 209
192 SetPath(pattern.substr(path_start_pos)); 210 SetPath(pattern.substr(path_start_pos));
193 211
194 if (strictness == PARSE_STRICT && host_.find(':') != std::string::npos) 212 std::string port = "*";
195 return PARSE_ERROR_HAS_COLON; 213 size_t port_pos = host_.find(':');
214 if (port_pos != std::string::npos) {
215 if (strictness == PARSE_STRICT)
216 return PARSE_ERROR_HAS_COLON;
217
218 if (!ignore_ports_)
219 port = host_.substr(port_pos + 1);
220
221 host_ = host_.substr(0, port_pos);
222 }
223 if (!SetPort(port))
224 return PARSE_ERROR_INVALID_PORT;
196 225
197 return PARSE_SUCCESS; 226 return PARSE_SUCCESS;
198 } 227 }
199 228
200 bool URLPattern::SetScheme(const std::string& scheme) { 229 bool URLPattern::SetScheme(const std::string& scheme) {
201 scheme_ = scheme; 230 scheme_ = scheme;
202 if (scheme_ == "*") { 231 if (scheme_ == "*") {
203 valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS); 232 valid_schemes_ &= (SCHEME_HTTP | SCHEME_HTTPS);
204 } else if (!IsValidScheme(scheme_)) { 233 } else if (!IsValidScheme(scheme_)) {
205 return false; 234 return false;
(...skipping 13 matching lines...) Expand all
219 return false; 248 return false;
220 } 249 }
221 250
222 void URLPattern::SetPath(const std::string& path) { 251 void URLPattern::SetPath(const std::string& path) {
223 path_ = path; 252 path_ = path;
224 path_escaped_ = path_; 253 path_escaped_ = path_;
225 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\"); 254 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "\\", "\\\\");
226 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?"); 255 ReplaceSubstringsAfterOffset(&path_escaped_, 0, "?", "\\?");
227 } 256 }
228 257
258 bool URLPattern::SetPort(const std::string& port) {
259 if (IsValidPort(port)) {
260 port_ = port;
261 return true;
262 }
263 return false;
264 }
265
229 bool URLPattern::MatchesURL(const GURL &test) const { 266 bool URLPattern::MatchesURL(const GURL &test) const {
230 if (!MatchesScheme(test.scheme())) 267 if (!MatchesScheme(test.scheme()))
231 return false; 268 return false;
232 269
233 if (match_all_urls_) 270 if (match_all_urls_)
234 return true; 271 return true;
235 272
236 // Ignore hostname if scheme is file://. 273 // Ignore hostname if scheme is file://.
237 if (scheme_ != chrome::kFileScheme && !MatchesHost(test)) 274 if (scheme_ != chrome::kFileScheme && !MatchesHost(test))
238 return false; 275 return false;
239 276
240 if (!MatchesPath(test.PathForRequest())) 277 if (!MatchesPath(test.PathForRequest()))
241 return false; 278 return false;
242 279
280 if (!MatchesPort(test.port()))
281 return false;
282
243 return true; 283 return true;
244 } 284 }
245 285
246 bool URLPattern::MatchesScheme(const std::string& test) const { 286 bool URLPattern::MatchesScheme(const std::string& test) const {
247 if (!IsValidScheme(test)) 287 if (!IsValidScheme(test))
248 return false; 288 return false;
249 289
250 return scheme_ == "*" || test == scheme_; 290 return scheme_ == "*" || test == scheme_;
251 } 291 }
252 292
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 return test.host()[test.host().length() - host_.length() - 1] == '.'; 329 return test.host()[test.host().length() - host_.length() - 1] == '.';
290 } 330 }
291 331
292 bool URLPattern::MatchesPath(const std::string& test) const { 332 bool URLPattern::MatchesPath(const std::string& test) const {
293 if (!MatchPattern(test, path_escaped_)) 333 if (!MatchPattern(test, path_escaped_))
294 return false; 334 return false;
295 335
296 return true; 336 return true;
297 } 337 }
298 338
339 bool URLPattern::MatchesPort(const std::string& test) const {
340 if (!IsValidPort(test))
341 return false;
342
343 return port_ == "*" || port_ == test;
344 }
345
299 std::string URLPattern::GetAsString() const { 346 std::string URLPattern::GetAsString() const {
300 if (match_all_urls_) 347 if (match_all_urls_)
301 return kAllUrlsPattern; 348 return kAllUrlsPattern;
302 349
303 bool standard_scheme = IsStandardScheme(scheme_); 350 bool standard_scheme = IsStandardScheme(scheme_);
304 351
305 std::string spec = scheme_ + 352 std::string spec = scheme_ +
306 (standard_scheme ? chrome::kStandardSchemeSeparator : ":"); 353 (standard_scheme ? chrome::kStandardSchemeSeparator : ":");
307 354
308 if (scheme_ != chrome::kFileScheme && standard_scheme) { 355 if (scheme_ != chrome::kFileScheme && standard_scheme) {
309 if (match_subdomains_) { 356 if (match_subdomains_) {
310 spec += "*"; 357 spec += "*";
311 if (!host_.empty()) 358 if (!host_.empty())
312 spec += "."; 359 spec += ".";
313 } 360 }
314 361
315 if (!host_.empty()) 362 if (!host_.empty())
316 spec += host_; 363 spec += host_;
364
365 if (!ignore_ports_ && !port_.empty()) {
366 spec += ":";
367 spec += port_;
368 }
317 } 369 }
318 370
319 if (!path_.empty()) 371 if (!path_.empty())
320 spec += path_; 372 spec += path_;
321 373
322 return spec; 374 return spec;
323 } 375 }
324 376
325 bool URLPattern::OverlapsWith(const URLPattern& other) const { 377 bool URLPattern::OverlapsWith(const URLPattern& other) const {
326 if (!MatchesAnyScheme(other.GetExplicitSchemes()) && 378 if (!MatchesAnyScheme(other.GetExplicitSchemes()) &&
327 !other.MatchesAnyScheme(GetExplicitSchemes())) { 379 !other.MatchesAnyScheme(GetExplicitSchemes())) {
328 return false; 380 return false;
329 } 381 }
330 382
331 if (!MatchesHost(other.host()) && !other.MatchesHost(host_)) 383 if (!MatchesHost(other.host()) && !other.MatchesHost(host_))
332 return false; 384 return false;
333 385
386 if (port_ != "*" && other.port() != "*" && port_ != other.port())
387 return false;
388
334 // We currently only use OverlapsWith() for the patterns inside 389 // We currently only use OverlapsWith() for the patterns inside
335 // URLPatternSet. In those cases, we know that the path will have only a 390 // URLPatternSet. In those cases, we know that the path will have only a
336 // single wildcard at the end. This makes figuring out overlap much easier. It 391 // single wildcard at the end. This makes figuring out overlap much easier. It
337 // seems like there is probably a computer-sciency way to solve the general 392 // seems like there is probably a computer-sciency way to solve the general
338 // case, but we don't need that yet. 393 // case, but we don't need that yet.
339 DCHECK(path_.find('*') == path_.size() - 1); 394 DCHECK(path_.find('*') == path_.size() - 1);
340 DCHECK(other.path().find('*') == other.path().size() - 1); 395 DCHECK(other.path().find('*') == other.path().size() - 1);
341 396
342 if (!MatchesPath(other.path().substr(0, other.path().size() - 1)) && 397 if (!MatchesPath(other.path().substr(0, other.path().size() - 1)) &&
343 !other.MatchesPath(path_.substr(0, path_.size() - 1))) 398 !other.MatchesPath(path_.substr(0, path_.size() - 1)))
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 442 }
388 443
389 return result; 444 return result;
390 } 445 }
391 446
392 // static 447 // static
393 const char* URLPattern::GetParseResultString( 448 const char* URLPattern::GetParseResultString(
394 URLPattern::ParseResult parse_result) { 449 URLPattern::ParseResult parse_result) {
395 return kParseResultMessages[parse_result]; 450 return kParseResultMessages[parse_result];
396 } 451 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698