123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127 |
- // Copyright 2020 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.
- #include "components/js_injection/common/origin_matcher.h"
- #include "base/containers/adapters.h"
- #include "components/js_injection/common/origin_matcher_internal.h"
- #include "net/base/ip_address.h"
- #include "net/base/ip_endpoint.h"
- #include "net/base/parse_number.h"
- #include "net/base/url_util.h"
- #include "url/gurl.h"
- #include "url/origin.h"
- #include "url/url_constants.h"
- #include "url/url_util.h"
- namespace js_injection {
- namespace {
- inline int GetDefaultPortForSchemeIfNoPortInfo(const std::string& scheme,
- int port) {
- // The input has explicit port information, so don't modify it.
- if (port != -1)
- return port;
- // Hard code the port for http and https.
- if (scheme == url::kHttpScheme)
- return 80;
- if (scheme == url::kHttpsScheme)
- return 443;
- return port;
- }
- } // namespace
- OriginMatcher::OriginMatcher(const OriginMatcher& rhs) {
- *this = rhs;
- }
- OriginMatcher& OriginMatcher::operator=(const OriginMatcher& rhs) {
- rules_.clear();
- for (const auto& rule : rhs.Serialize())
- AddRuleFromString(rule);
- return *this;
- }
- void OriginMatcher::SetRules(RuleList rules) {
- rules_.swap(rules);
- }
- bool OriginMatcher::AddRuleFromString(const std::string& raw_untrimmed) {
- std::string raw;
- base::TrimWhitespaceASCII(raw_untrimmed, base::TRIM_ALL, &raw);
- if (raw == "*") {
- rules_.push_back(std::make_unique<MatchAllOriginsRule>());
- return true;
- }
- // Extract scheme-restriction.
- std::string::size_type scheme_pos = raw.find("://");
- if (scheme_pos == std::string::npos)
- return false;
- const std::string scheme = raw.substr(0, scheme_pos);
- if (!SubdomainMatchingRule::IsValidScheme(scheme))
- return false;
- std::string host_and_port = raw.substr(scheme_pos + 3);
- if (host_and_port.empty()) {
- if (!SubdomainMatchingRule::IsValidSchemeAndHost(scheme, std::string()))
- return false;
- rules_.push_back(
- std::make_unique<SubdomainMatchingRule>(scheme, std::string(), -1));
- return true;
- }
- std::string host;
- int port;
- if (!net::ParseHostAndPort(host_and_port, &host, &port) ||
- !SubdomainMatchingRule::IsValidSchemeAndHost(scheme, host)) {
- return false;
- }
- // Check if we have an <ip-address>[:port] input and try to canonicalize the
- // IP literal.
- net::IPAddress ip_address;
- if (ip_address.AssignFromIPLiteral(host)) {
- port = GetDefaultPortForSchemeIfNoPortInfo(scheme, port);
- host = ip_address.ToString();
- if (ip_address.IsIPv6())
- host = '[' + host + ']';
- rules_.push_back(
- std::make_unique<SubdomainMatchingRule>(scheme, host, port));
- return true;
- }
- port = GetDefaultPortForSchemeIfNoPortInfo(scheme, port);
- rules_.push_back(std::make_unique<SubdomainMatchingRule>(scheme, host, port));
- return true;
- }
- bool OriginMatcher::Matches(const url::Origin& origin) const {
- GURL origin_url = origin.GetURL();
- // Since we only do kInclude vs kNoMatch, the order doesn't actually matter.
- for (const std::unique_ptr<OriginMatcherRule>& rule :
- base::Reversed(rules_)) {
- net::SchemeHostPortMatcherResult result = rule->Evaluate(origin_url);
- if (result == net::SchemeHostPortMatcherResult::kInclude)
- return true;
- }
- return false;
- }
- std::vector<std::string> OriginMatcher::Serialize() const {
- std::vector<std::string> result;
- result.reserve(rules_.size());
- for (const auto& rule : rules_) {
- result.push_back(rule->ToString());
- }
- return result;
- }
- } // namespace js_injection
|