| OLD | NEW |
| 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/content_settings_pattern.h" | 5 #include "chrome/common/content_settings_pattern.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 10 #include "base/string_split.h" | 10 #include "base/string_split.h" |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 123 | 123 |
| 124 BuilderInterface* ContentSettingsPattern::Builder::WithSchemeWildcard() { | 124 BuilderInterface* ContentSettingsPattern::Builder::WithSchemeWildcard() { |
| 125 parts_.scheme = ""; | 125 parts_.scheme = ""; |
| 126 parts_.is_scheme_wildcard = true; | 126 parts_.is_scheme_wildcard = true; |
| 127 return this; | 127 return this; |
| 128 } | 128 } |
| 129 | 129 |
| 130 BuilderInterface* ContentSettingsPattern::Builder::WithPath( | 130 BuilderInterface* ContentSettingsPattern::Builder::WithPath( |
| 131 const std::string& path) { | 131 const std::string& path) { |
| 132 parts_.path = path; | 132 parts_.path = path; |
| 133 parts_.is_path_wildcard = false; |
| 134 return this; |
| 135 } |
| 136 |
| 137 BuilderInterface* ContentSettingsPattern::Builder::WithPathWildcard() { |
| 138 parts_.path = ""; |
| 139 parts_.is_path_wildcard = true; |
| 133 return this; | 140 return this; |
| 134 } | 141 } |
| 135 | 142 |
| 136 BuilderInterface* ContentSettingsPattern::Builder::Invalid() { | 143 BuilderInterface* ContentSettingsPattern::Builder::Invalid() { |
| 137 is_valid_ = false; | 144 is_valid_ = false; |
| 138 return this; | 145 return this; |
| 139 } | 146 } |
| 140 | 147 |
| 141 ContentSettingsPattern ContentSettingsPattern::Builder::Build() { | 148 ContentSettingsPattern ContentSettingsPattern::Builder::Build() { |
| 142 if (!is_valid_) | 149 if (!is_valid_) |
| 143 return ContentSettingsPattern(); | 150 return ContentSettingsPattern(); |
| 144 if (!Canonicalize(&parts_)) | 151 if (!Canonicalize(&parts_)) |
| 145 return ContentSettingsPattern(); | 152 return ContentSettingsPattern(); |
| 146 if (use_legacy_validate_) { | 153 if (use_legacy_validate_) { |
| 147 is_valid_ = LegacyValidate(parts_); | 154 is_valid_ = LegacyValidate(parts_); |
| 148 } else { | 155 } else { |
| 149 is_valid_ = Validate(parts_); | 156 is_valid_ = Validate(parts_); |
| 150 } | 157 } |
| 151 return ContentSettingsPattern(parts_, is_valid_); | 158 return ContentSettingsPattern(parts_, is_valid_); |
| 152 } | 159 } |
| 153 | 160 |
| 154 // static | 161 // static |
| 155 bool ContentSettingsPattern::Builder::Canonicalize(PatternParts* parts) { | 162 bool ContentSettingsPattern::Builder::Canonicalize(PatternParts* parts) { |
| 156 // Canonicalize the scheme part. | 163 // Canonicalize the scheme part. |
| 157 const std::string scheme(StringToLowerASCII(parts->scheme)); | 164 const std::string scheme(StringToLowerASCII(parts->scheme)); |
| 158 parts->scheme = scheme; | 165 parts->scheme = scheme; |
| 159 | 166 |
| 160 if (parts->scheme == std::string(chrome::kFileScheme)) { | 167 if (parts->scheme == std::string(chrome::kFileScheme) && |
| 161 GURL url(std::string(chrome::kFileScheme) + | 168 !parts->is_path_wildcard) { |
| 162 std::string(chrome::kStandardSchemeSeparator) + parts->path); | 169 GURL url(std::string(chrome::kFileScheme) + |
| 163 parts->path = url.path(); | 170 std::string(chrome::kStandardSchemeSeparator) + parts->path); |
| 171 parts->path = url.path(); |
| 164 } | 172 } |
| 165 | 173 |
| 166 // Canonicalize the host part. | 174 // Canonicalize the host part. |
| 167 const std::string host(parts->host); | 175 const std::string host(parts->host); |
| 168 url_canon::CanonHostInfo host_info; | 176 url_canon::CanonHostInfo host_info; |
| 169 std::string canonicalized_host(net::CanonicalizeHost(host, &host_info)); | 177 std::string canonicalized_host(net::CanonicalizeHost(host, &host_info)); |
| 170 if (host_info.IsIPAddress() && parts->has_domain_wildcard) | 178 if (host_info.IsIPAddress() && parts->has_domain_wildcard) |
| 171 return false; | 179 return false; |
| 172 canonicalized_host = net::TrimEndingDot(canonicalized_host); | 180 canonicalized_host = net::TrimEndingDot(canonicalized_host); |
| 173 | 181 |
| 174 parts->host = ""; | 182 parts->host = ""; |
| 175 if ((host.find('*') == std::string::npos) && | 183 if ((host.find('*') == std::string::npos) && |
| 176 !canonicalized_host.empty()) { | 184 !canonicalized_host.empty()) { |
| 177 // Valid host. | 185 // Valid host. |
| 178 parts->host += canonicalized_host; | 186 parts->host += canonicalized_host; |
| 179 } | 187 } |
| 180 return true; | 188 return true; |
| 181 } | 189 } |
| 182 | 190 |
| 183 // static | 191 // static |
| 184 bool ContentSettingsPattern::Builder::Validate(const PatternParts& parts) { | 192 bool ContentSettingsPattern::Builder::Validate(const PatternParts& parts) { |
| 185 // Sanity checks first: {scheme, port} wildcards imply empty {scheme, port}. | 193 // Sanity checks first: {scheme, port} wildcards imply empty {scheme, port}. |
| 186 if ((parts.is_scheme_wildcard && !parts.scheme.empty()) || | 194 if ((parts.is_scheme_wildcard && !parts.scheme.empty()) || |
| 187 (parts.is_port_wildcard && !parts.port.empty())) { | 195 (parts.is_port_wildcard && !parts.port.empty())) { |
| 188 NOTREACHED(); | 196 NOTREACHED(); |
| 189 return false; | 197 return false; |
| 190 } | 198 } |
| 191 | 199 |
| 192 // file:// URL patterns have an empty host and port. | 200 // file:// URL patterns have an empty host and port. |
| 193 if (parts.scheme == std::string(chrome::kFileScheme)) | 201 if (parts.scheme == std::string(chrome::kFileScheme)) { |
| 194 return parts.host.empty() && | 202 if (parts.has_domain_wildcard || !parts.host.empty() || !parts.port.empty()) |
| 195 parts.port.empty() && | 203 return false; |
| 196 !parts.path.empty() && | 204 if (parts.is_path_wildcard) |
| 197 parts.path != std::string("/") && | 205 return parts.path.empty(); |
| 198 parts.path.find("*") == std::string::npos; | 206 return (!parts.path.empty() && |
| 207 parts.path != "/" && |
| 208 parts.path.find("*") == std::string::npos); |
| 209 } |
| 199 | 210 |
| 200 // If the pattern is for an extension URL test if it is valid. | 211 // If the pattern is for an extension URL test if it is valid. |
| 201 if (parts.scheme == std::string(chrome::kExtensionScheme) && | 212 if (parts.scheme == std::string(chrome::kExtensionScheme) && |
| 202 !parts.host.empty() && | 213 !parts.host.empty() && |
| 203 !parts.has_domain_wildcard && | 214 !parts.has_domain_wildcard && |
| 204 parts.port.empty() && | 215 parts.port.empty() && |
| 205 !parts.is_port_wildcard) { | 216 !parts.is_port_wildcard) { |
| 206 return true; | 217 return true; |
| 207 } | 218 } |
| 208 | 219 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 260 } | 271 } |
| 261 return true; | 272 return true; |
| 262 } | 273 } |
| 263 | 274 |
| 264 // //////////////////////////////////////////////////////////////////////////// | 275 // //////////////////////////////////////////////////////////////////////////// |
| 265 // ContentSettingsPattern::PatternParts | 276 // ContentSettingsPattern::PatternParts |
| 266 // | 277 // |
| 267 ContentSettingsPattern::PatternParts::PatternParts() | 278 ContentSettingsPattern::PatternParts::PatternParts() |
| 268 : is_scheme_wildcard(false), | 279 : is_scheme_wildcard(false), |
| 269 has_domain_wildcard(false), | 280 has_domain_wildcard(false), |
| 270 is_port_wildcard(false) {} | 281 is_port_wildcard(false), |
| 282 is_path_wildcard(false) {} |
| 271 | 283 |
| 272 ContentSettingsPattern::PatternParts::~PatternParts() {} | 284 ContentSettingsPattern::PatternParts::~PatternParts() {} |
| 273 | 285 |
| 274 // //////////////////////////////////////////////////////////////////////////// | 286 // //////////////////////////////////////////////////////////////////////////// |
| 275 // ContentSettingsPattern | 287 // ContentSettingsPattern |
| 276 // | 288 // |
| 277 | 289 |
| 278 // The version of the pattern format implemented. Version 1 includes the | 290 // The version of the pattern format implemented. Version 1 includes the |
| 279 // following patterns: | 291 // following patterns: |
| 280 // - [*.]domain.tld (matches domain.tld and all sub-domains) | 292 // - [*.]domain.tld (matches domain.tld and all sub-domains) |
| (...skipping 16 matching lines...) Expand all Loading... |
| 297 return new Builder(validate); | 309 return new Builder(validate); |
| 298 } | 310 } |
| 299 | 311 |
| 300 // static | 312 // static |
| 301 ContentSettingsPattern ContentSettingsPattern::FromURL( | 313 ContentSettingsPattern ContentSettingsPattern::FromURL( |
| 302 const GURL& url) { | 314 const GURL& url) { |
| 303 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( | 315 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( |
| 304 ContentSettingsPattern::CreateBuilder(false)); | 316 ContentSettingsPattern::CreateBuilder(false)); |
| 305 | 317 |
| 306 if (url.SchemeIsFile()) { | 318 if (url.SchemeIsFile()) { |
| 307 builder->WithScheme(url.scheme())->WithPath(url.path()); | 319 builder->WithScheme(url.scheme()); |
| 320 // Matches GURL("file:///"). |
| 321 if (url.path() == "/") { |
| 322 builder->WithPathWildcard(); |
| 323 } else { |
| 324 builder->WithPath(url.path()); |
| 325 } |
| 308 } else { | 326 } else { |
| 309 // Please keep the order of the ifs below as URLs with an IP as host can | 327 // Please keep the order of the ifs below as URLs with an IP as host can |
| 310 // also have a "http" scheme. | 328 // also have a "http" scheme. |
| 311 if (url.HostIsIPAddress()) { | 329 if (url.HostIsIPAddress()) { |
| 312 builder->WithScheme(url.scheme())->WithHost(url.host()); | 330 builder->WithScheme(url.scheme())->WithHost(url.host()); |
| 313 } else if (url.SchemeIs(chrome::kHttpScheme)) { | 331 } else if (url.SchemeIs(chrome::kHttpScheme)) { |
| 314 builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(url.host()); | 332 builder->WithSchemeWildcard()->WithDomainWildcard()->WithHost(url.host()); |
| 315 } else if (url.SchemeIs(chrome::kHttpsScheme)) { | 333 } else if (url.SchemeIs(chrome::kHttpsScheme)) { |
| 316 builder->WithScheme(url.scheme())->WithDomainWildcard()->WithHost( | 334 builder->WithScheme(url.scheme())->WithDomainWildcard()->WithHost( |
| 317 url.host()); | 335 url.host()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 364 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( | 382 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( |
| 365 ContentSettingsPattern::CreateBuilder(true)); | 383 ContentSettingsPattern::CreateBuilder(true)); |
| 366 content_settings::PatternParser::Parse(pattern_spec, builder.get()); | 384 content_settings::PatternParser::Parse(pattern_spec, builder.get()); |
| 367 return builder->Build(); | 385 return builder->Build(); |
| 368 } | 386 } |
| 369 | 387 |
| 370 // static | 388 // static |
| 371 ContentSettingsPattern ContentSettingsPattern::Wildcard() { | 389 ContentSettingsPattern ContentSettingsPattern::Wildcard() { |
| 372 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( | 390 scoped_ptr<ContentSettingsPattern::BuilderInterface> builder( |
| 373 ContentSettingsPattern::CreateBuilder(true)); | 391 ContentSettingsPattern::CreateBuilder(true)); |
| 374 builder->WithSchemeWildcard()->WithDomainWildcard()->WithPortWildcard(); | 392 builder->WithSchemeWildcard()->WithDomainWildcard()->WithPortWildcard()-> |
| 393 WithPathWildcard(); |
| 375 return builder->Build(); | 394 return builder->Build(); |
| 376 } | 395 } |
| 377 | 396 |
| 378 ContentSettingsPattern::ContentSettingsPattern() | 397 ContentSettingsPattern::ContentSettingsPattern() |
| 379 : is_valid_(false) { | 398 : is_valid_(false) { |
| 380 } | 399 } |
| 381 | 400 |
| 382 ContentSettingsPattern::ContentSettingsPattern( | 401 ContentSettingsPattern::ContentSettingsPattern( |
| 383 const PatternParts& parts, | 402 const PatternParts& parts, |
| 384 bool valid) | 403 bool valid) |
| (...skipping 18 matching lines...) Expand all Loading... |
| 403 if (!is_valid_) | 422 if (!is_valid_) |
| 404 return false; | 423 return false; |
| 405 | 424 |
| 406 // Match the scheme part. | 425 // Match the scheme part. |
| 407 const std::string scheme(url.scheme()); | 426 const std::string scheme(url.scheme()); |
| 408 if (!parts_.is_scheme_wildcard && | 427 if (!parts_.is_scheme_wildcard && |
| 409 parts_.scheme != scheme) { | 428 parts_.scheme != scheme) { |
| 410 return false; | 429 return false; |
| 411 } | 430 } |
| 412 | 431 |
| 413 // File URLs have no host. For file URLs check if the url path matches the | 432 // File URLs have no host. Matches if the pattern has the path wildcard set, |
| 414 // path in the pattern. | 433 // or if the path in the URL is identical to the one in the pattern. |
| 415 // TODO(markusheintz): This should change in the future. There should be only | 434 if (!parts_.is_scheme_wildcard && scheme == chrome::kFileScheme) |
| 416 // one setting for all file URLs. So the path should be ignored. | 435 return parts_.is_path_wildcard || parts_.path == std::string(url.path()); |
| 417 if (!parts_.is_scheme_wildcard && | |
| 418 scheme == std::string(chrome::kFileScheme)) { | |
| 419 if (parts_.path == std::string(url.path())) | |
| 420 return true; | |
| 421 return false; | |
| 422 } | |
| 423 | 436 |
| 424 // Match the host part. | 437 // Match the host part. |
| 425 const std::string host(net::TrimEndingDot(url.host())); | 438 const std::string host(net::TrimEndingDot(url.host())); |
| 426 if (!parts_.has_domain_wildcard) { | 439 if (!parts_.has_domain_wildcard) { |
| 427 if (parts_.host != host) | 440 if (parts_.host != host) |
| 428 return false; | 441 return false; |
| 429 } else { | 442 } else { |
| 430 if (!IsSubDomainOrEqual(host, parts_.host)) | 443 if (!IsSubDomainOrEqual(host, parts_.host)) |
| 431 return false; | 444 return false; |
| 432 } | 445 } |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 if (!parts.is_port_wildcard && other_parts.is_port_wildcard) | 643 if (!parts.is_port_wildcard && other_parts.is_port_wildcard) |
| 631 return ContentSettingsPattern::PREDECESSOR; | 644 return ContentSettingsPattern::PREDECESSOR; |
| 632 | 645 |
| 633 int result = parts.port.compare(other_parts.port); | 646 int result = parts.port.compare(other_parts.port); |
| 634 if (result == 0) | 647 if (result == 0) |
| 635 return ContentSettingsPattern::IDENTITY; | 648 return ContentSettingsPattern::IDENTITY; |
| 636 if (result > 0) | 649 if (result > 0) |
| 637 return ContentSettingsPattern::DISJOINT_ORDER_PRE; | 650 return ContentSettingsPattern::DISJOINT_ORDER_PRE; |
| 638 return ContentSettingsPattern::DISJOINT_ORDER_POST; | 651 return ContentSettingsPattern::DISJOINT_ORDER_POST; |
| 639 } | 652 } |
| OLD | NEW |