// Copyright 2015 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/csp/content_security_policy.h"

#include "base/string_util.h"
#include "base/values.h"
#include "cobalt/csp/directive_list.h"
#include "cobalt/csp/source.h"

namespace cobalt {
namespace csp {

namespace {

ReferrerPolicy MergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) {
  // If there are conflicting policies, err on the side of security, i.e.
  // send no referrer. This could happen if there is a CSP policy in the
  // response headers from the server and then a different one in a <meta>
  // in the document.
  if (a != b) {
    return kReferrerPolicyNoReferrer;
  } else {
    return a;
  }
}

// Macros for iterating over the CSP's policies_ list and
// calling a given function.
#define FOR_ALL_POLICIES_1(AllowFunc, arg0)               \
  for (PolicyList::const_iterator it = policies_.begin(); \
       it != policies_.end(); ++it) {                     \
    if (!(*it)->AllowFunc((arg0))) return false;          \
  }                                                       \
  return true

#define FOR_ALL_POLICIES_3(AllowFunc, arg0, arg1, arg2)                  \
  for (PolicyList::const_iterator it = policies_.begin();                \
       it != policies_.end(); ++it) {                                    \
    if ((*it)->AllowFunc((arg0), (arg1), (arg2)) == false) return false; \
  }                                                                      \
  return true

#define FOR_ALL_POLICIES_4(AllowFunc, arg0, arg1, arg2, arg3)        \
  for (PolicyList::const_iterator it = policies_.begin();            \
       it != policies_.end(); ++it) {                                \
    if ((*it)->AllowFunc((arg0), (arg1), (arg2), (arg3)) == false) { \
      return false;                                                  \
    }                                                                \
  }                                                                  \
  return true

// Similar to above but templatized on a member variable.
// Used by CheckDigest().
template <bool (DirectiveList::*allowed)(const HashValue&) const>
bool IsAllowedByAllWithHash(const ContentSecurityPolicy::PolicyList& policies,
                            const HashValue& hash_value) {
  for (ContentSecurityPolicy::PolicyList::const_iterator it = policies.begin();
       it != policies.end(); ++it) {
    if (!(*it->*allowed)(hash_value)) {
      return false;
    }
  }
  return true;
}

template <bool (DirectiveList::*allowed)(const HashValue&) const>
bool CheckDigest(const std::string& source, uint8 hash_algorithms_used,
                 const ContentSecurityPolicy::PolicyList& policies) {
  if (hash_algorithms_used == kHashAlgorithmNone) {
    return false;
  }

  HashAlgorithm valid_hash_algorithms[] = {
      kHashAlgorithmSha256, kHashAlgorithmSha384, kHashAlgorithmSha512,
  };

  for (size_t i = 0; i < arraysize(valid_hash_algorithms); ++i) {
    DigestValue digest;
    if (valid_hash_algorithms[i] & hash_algorithms_used) {
      bool digest_success = ComputeDigest(
          valid_hash_algorithms[i], source.c_str(), source.length(), &digest);
      if (digest_success &&
          IsAllowedByAllWithHash<allowed>(
              policies, HashValue(valid_hash_algorithms[i], digest))) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace

ResponseHeaders::ResponseHeaders(
    const scoped_refptr<net::HttpResponseHeaders>& response) {
  response->GetNormalizedHeader("Content-Security-Policy",
                                &content_security_policy_);
  response->GetNormalizedHeader("Content-Security-Policy-Report-Only",
                                &content_security_policy_report_only_);
}

// CSP Level 1 Directives
const char ContentSecurityPolicy::kConnectSrc[] = "connect-src";
const char ContentSecurityPolicy::kDefaultSrc[] = "default-src";
const char ContentSecurityPolicy::kFontSrc[] = "font-src";
const char ContentSecurityPolicy::kFrameSrc[] = "frame-src";
const char ContentSecurityPolicy::kImgSrc[] = "img-src";
const char ContentSecurityPolicy::kMediaSrc[] = "media-src";
const char ContentSecurityPolicy::kObjectSrc[] = "object-src";
const char ContentSecurityPolicy::kReportURI[] = "report-uri";
const char ContentSecurityPolicy::kSandbox[] = "sandbox";
const char ContentSecurityPolicy::kScriptSrc[] = "script-src";
const char ContentSecurityPolicy::kStyleSrc[] = "style-src";

// CSP Level 2 Directives
const char ContentSecurityPolicy::kBaseURI[] = "base-uri";
const char ContentSecurityPolicy::kChildSrc[] = "child-src";
const char ContentSecurityPolicy::kFormAction[] = "form-action";
const char ContentSecurityPolicy::kFrameAncestors[] = "frame-ancestors";
const char ContentSecurityPolicy::kPluginTypes[] = "plugin-types";
const char ContentSecurityPolicy::kReflectedXSS[] = "reflected-xss";
const char ContentSecurityPolicy::kReferrer[] = "referrer";

// Custom Cobalt directive to enforce navigation restrictions.
const char ContentSecurityPolicy::kLocationSrc[] = "h5vcc-location-src";

// CSP Editor's Draft:
// https://w3c.github.io/webappsec/specs/content-security-policy
const char ContentSecurityPolicy::kManifestSrc[] = "manifest-src";

// Mixed Content Directive
// https://w3c.github.io/webappsec/specs/mixedcontent/#strict-mode
const char ContentSecurityPolicy::kBlockAllMixedContent[] =
    "block-all-mixed-content";

// https://w3c.github.io/webappsec/specs/upgrade/
const char ContentSecurityPolicy::kUpgradeInsecureRequests[] =
    "upgrade-insecure-requests";

// Suborigin Directive
// https://metromoxie.github.io/webappsec/specs/suborigins/index.html
const char ContentSecurityPolicy::kSuborigin[] = "suborigin";

// clang-format off
bool ContentSecurityPolicy::IsDirectiveName(const std::string& name) {
  std::string lower_name = StringToLowerASCII(name);
  return (lower_name == kConnectSrc ||
          lower_name == kDefaultSrc ||
          lower_name == kFontSrc ||
          lower_name == kFrameSrc ||
          lower_name == kImgSrc ||
          lower_name == kLocationSrc ||
          lower_name == kMediaSrc ||
          lower_name == kObjectSrc ||
          lower_name == kReportURI ||
          lower_name == kSandbox ||
          lower_name == kSuborigin ||
          lower_name == kScriptSrc ||
          lower_name == kStyleSrc ||
          lower_name == kBaseURI ||
          lower_name == kChildSrc ||
          lower_name == kFormAction ||
          lower_name == kFrameAncestors ||
          lower_name == kPluginTypes ||
          lower_name == kReflectedXSS ||
          lower_name == kReferrer ||
          lower_name == kManifestSrc ||
          lower_name == kBlockAllMixedContent ||
          lower_name == kUpgradeInsecureRequests);
}
// clang-format on

ContentSecurityPolicy::ContentSecurityPolicy(
    const GURL& url, const ViolationCallback& violation_callback)
    : violation_callback_(violation_callback),
      script_hash_algorithms_used_(0),
      style_hash_algorithms_used_(0),
      enforce_strict_mixed_content_checking_(false),
      referrer_policy_(kReferrerPolicyDefault) {
  NotifyUrlChanged(url);
}

ContentSecurityPolicy::~ContentSecurityPolicy() {}

void ContentSecurityPolicy::OnReceiveHeaders(const ResponseHeaders& headers) {
  if (!headers.content_security_policy().empty()) {
    AddPolicyFromHeaderValue(headers.content_security_policy(),
                             kHeaderTypeEnforce, kHeaderSourceHTTP);
  }
  if (!headers.content_security_policy_report_only().empty()) {
    AddPolicyFromHeaderValue(headers.content_security_policy_report_only(),
                             kHeaderTypeReport, kHeaderSourceHTTP);
  }
}

void ContentSecurityPolicy::OnReceiveHeader(const std::string& header,
                                            HeaderType type,
                                            HeaderSource source) {
  AddPolicyFromHeaderValue(header, type, source);
}

void ContentSecurityPolicy::SetNavigationPolicy(const std::string& policy) {
  navigation_policy_.reset(new DirectiveList(
      this, base::StringPiece(policy), kHeaderTypeEnforce, kHeaderSourceHTTP));
}

bool ContentSecurityPolicy::UrlMatchesSelf(const GURL& url) const {
  return self_source_->Matches(url, kDidNotRedirect);
}

bool ContentSecurityPolicy::SchemeMatchesSelf(const GURL& url) const {
  // https://www.w3.org/TR/CSP2/#match-source-expression, section 4.5.1
  // Allow "upgrade" to https if our document is http.
  if (LowerCaseEqualsASCII(self_scheme_, "http")) {
    return url.SchemeIs("http") || url.SchemeIs("https");
  } else {
    return self_scheme_ == url.scheme();
  }
}

void ContentSecurityPolicy::ReportViolation(
    const std::string& directive_text, const std::string& effective_directive,
    const std::string& console_message, const GURL& blocked_url,
    const std::vector<std::string>& report_endpoints,
    const std::string& header) {
  if (violation_callback_.is_null()) {
    return;
  }

  ViolationInfo violation_info;
  violation_info.directive_text = directive_text;
  violation_info.effective_directive = effective_directive;
  violation_info.console_message = console_message;
  violation_info.blocked_url = blocked_url;
  violation_info.endpoints = report_endpoints;
  violation_info.header = header;
  violation_callback_.Run(violation_info);
}

void ContentSecurityPolicy::ReportInvalidReferrer(
    const std::string& invalid_value) {
  std::string message =
      "The 'referrer' Content Security Policy directive has the invalid value "
      "\"" +
      invalid_value +
      "\". Valid values are \"no-referrer\", \"no-referrer-when-downgrade\", "
      "\"origin\", \"origin-when-cross-origin\", and \"unsafe-url\".";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidPluginTypes(
    const std::string& plugin_type) {
  std::string message;
  if (plugin_type.empty()) {
    message =
        "'plugin-types' Content Security Policy directive is empty; all "
        "plugins will be blocked.\n";
  } else if (plugin_type == "'none'") {
    message =
        "Invalid plugin type in 'plugin-types' Content Security Policy "
        "directive: '";
    message += plugin_type;
    message += "'. Did you mean to set the object-src directive to 'none'?\n";
  } else {
    message =
        "Invalid plugin type in 'plugin-types' Content Security Policy "
        "directive: '";
    message += plugin_type;
    message += "'.\n";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportMetaOutsideHead(const std::string& header) {
  std::string message = "The Content Security Policy '" + header +
                        "' was delivered via a <meta> element outside the "
                        "document's <head>, which is disallowed. The policy "
                        "has been ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportValueForEmptyDirective(
    const std::string& name, const std::string& value) {
  std::string message =
      "The Content Security Policy directive '" + name +
      "' should be empty, but was delivered with a value of '" + value +
      "'. The directive has been applied, and the value ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDirectiveAsSourceExpression(
    const std::string& directive_name, const std::string& source_expression) {
  std::string message = "The Content Security Policy directive '" +
                        directive_name + "' contains '" + source_expression +
                        "' as a source expression. Did you mean '" +
                        directive_name + " ...; " + source_expression +
                        "...' (note the semicolon)?";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidSourceExpression(
    const std::string& directive_name, const std::string& source) {
  std::string message =
      "The source list for Content Security Policy directive '" +
      directive_name + "' contains an invalid source: '" + source +
      "'. It will be ignored.";
  if (LowerCaseEqualsASCII(source.c_str(), "'none'")) {
    message = message +
              " Note that 'none' has no effect unless it is the only "
              "expression in the source list.";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidPathCharacter(
    const std::string& directive_name, const std::string& value,
    char invalid_char) {
  DCHECK(invalid_char == '#' || invalid_char == '?');
  std::string message =
      "The source list for Content Security Policy directive '";
  message += directive_name;
  message += "' contains a source with an invalid path: '";
  message += value;
  message += "'. ";
  message +=
      invalid_char == '?'
          ? "The query component, including the '?', will be ignored."
          : "The fragment identifier, including the '#', will be ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDuplicateDirective(const std::string& name) {
  std::string message =
      "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidDirectiveValueCharacter(
    const std::string& directive_name, const std::string& value) {
  std::string message =
      "The value for Content Security Policy directive '" + directive_name +
      "' contains an invalid character: '" + value +
      "'. Non-whitespace characters outside ASCII 0x21-0x7E must be "
      "percent-encoded, as described in RFC 3986, section 2.1: "
      "http://tools.ietf.org/html/rfc3986#section-2.1.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidReflectedXSS(
    const std::string& invalid_value) {
  std::string message =
      "The 'reflected-xss' Content Security Policy directive has the invalid "
      "value \"" +
      invalid_value +
      "\". Valid values are \"allow\", \"filter\", and \"block\".";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportMissingReportURI(const std::string& policy) {
  std::string message = "The Content Security Policy '";
  message += policy;
  message +=
      "' was delivered in report-only mode, but does not specify a "
      "'report-uri'; the policy will have no effect. Please either add a "
      "'report-uri' directive, or deliver the policy via the "
      "'Content-Security-Policy' header.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportReportOnlyInMeta(const std::string& header) {
  std::string message = "The report-only Content Security Policy '" + header +
                        "' was delivered via a <meta> element, which is "
                        "disallowed. The policy has been ignored.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidSuboriginFlags(
    const std::string& invalid_flags) {
  std::string message =
      "Error while parsing the 'suborigin' Content Security Policy "
      "directive: " +
      invalid_flags;
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportUnsupportedDirective(
    const std::string& name) {
  std::string lower_name = StringToLowerASCII(name);
  std::string message;
  if (lower_name == "allow") {
    message =
        "The 'allow' directive has been replaced with 'default-src'. Please "
        "use that directive instead, as 'allow' has no effect.";
  } else if (lower_name == "options") {
    message =
        "The 'options' directive has been replaced with 'unsafe-inline' and "
        "'unsafe-eval' source expressions for the 'script-src' and 'style-src' "
        "directives. Please use those directives instead, as 'options' has no "
        "effect.";
  } else if (lower_name == "policy-uri") {
    message =
        "The 'policy-uri' directive has been removed from the specification. "
        "Please specify a complete policy via the Content-Security-Policy "
        "header.";
  } else if (IsDirectiveName(name)) {
    message = "The Content-Security-Policy directive '" + name +
              "' is implemented behind a flag which is currently disabled.\n";
  } else {
    message =
        "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
  }
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportInvalidInReportOnly(const std::string& name) {
  std::string message = "The Content Security Policy directive '" + name +
                        "' is ignored when delivered in a report-only policy.";
  DLOG(WARNING) << message;
}

void ContentSecurityPolicy::ReportDirectiveNotSupportedInsideMeta(
    const std::string& name) {
  DLOG(WARNING) << "The " << name
                << " directive is not supported inside a <meta> element.";
}

bool ContentSecurityPolicy::AllowJavaScriptURLs(const std::string& context_url,
                                                int context_line,
                                                ReportingStatus status) const {
  FOR_ALL_POLICIES_3(AllowJavaScriptURLs, context_url, context_line, status);
}

bool ContentSecurityPolicy::AllowInlineEventHandlers(
    const std::string& context_url, int context_line,
    ReportingStatus status) const {
  FOR_ALL_POLICIES_3(AllowInlineEventHandlers, context_url, context_line,
                     status);
}
bool ContentSecurityPolicy::AllowInlineScript(const std::string& context_url,
                                              int context_line,
                                              const std::string& script_content,
                                              ReportingStatus status) const {
  FOR_ALL_POLICIES_4(AllowInlineScript, context_url, context_line, status,
                     script_content);
}
bool ContentSecurityPolicy::AllowInlineStyle(const std::string& context_url,
                                             int context_line,
                                             const std::string& style_content,
                                             ReportingStatus status) const {
  FOR_ALL_POLICIES_4(AllowInlineStyle, context_url, context_line, status,
                     style_content);
}

bool ContentSecurityPolicy::AllowEval(ReportingStatus status) const {
  FOR_ALL_POLICIES_1(AllowEval, status);
}

bool ContentSecurityPolicy::AllowScriptFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowScriptFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowObjectFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowObjectFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowImageFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowImageFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowNavigateToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  // Note that this is a Cobalt-specific policy to prevent navigation
  // to any unexpected URLs. Navigation is restrictive by default, as
  // opposed to the permissive policy for other directives.

  if (!navigation_policy_) {
    DLOG(ERROR) << "SetNavigationFallbackPolicy() was not called.";
    return false;
  }
  // TODO: Re-enable respecting the navigation whitelist.
  return navigation_policy_->AllowNavigateToSource(url, redirect_status,
                                                   reporting_status);
}

bool ContentSecurityPolicy::AllowStyleFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowStyleFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowFontFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowFontFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowMediaFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowMediaFromSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowConnectToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowConnectToSource, url, redirect_status,
                     reporting_status);
}

bool ContentSecurityPolicy::AllowFormAction(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowFormAction, url, redirect_status, reporting_status);
}

bool ContentSecurityPolicy::AllowBaseURI(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowBaseURI, url, redirect_status, reporting_status);
}

bool ContentSecurityPolicy::AllowManifestFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  FOR_ALL_POLICIES_3(AllowManifestFromSource, url, redirect_status,
                     reporting_status);
}
bool ContentSecurityPolicy::AllowScriptWithNonce(
    const std::string& nonce) const {
  FOR_ALL_POLICIES_1(AllowScriptNonce, nonce);
}

bool ContentSecurityPolicy::AllowStyleWithNonce(
    const std::string& nonce) const {
  FOR_ALL_POLICIES_1(AllowStyleNonce, nonce);
}

bool ContentSecurityPolicy::AllowScriptWithHash(
    const std::string& source) const {
  return CheckDigest<&DirectiveList::AllowScriptHash>(
      source, script_hash_algorithms_used_, policies_);
}

bool ContentSecurityPolicy::AllowStyleWithHash(
    const std::string& source) const {
  return CheckDigest<&DirectiveList::AllowStyleHash>(
      source, style_hash_algorithms_used_, policies_);
}

void ContentSecurityPolicy::NotifyUrlChanged(const GURL& url) {
  url_ = url;
  CreateSelfSource();
}

bool ContentSecurityPolicy::DidSetReferrerPolicy() const {
  for (PolicyList::const_iterator it = policies_.begin(); it != policies_.end();
       ++it) {
    if ((*it)->did_set_referrer_policy()) {
      return true;
    }
  }
  return false;
}

void ContentSecurityPolicy::CreateSelfSource() {
  // Ensure that 'self' processes correctly.
  self_scheme_ = url_.scheme();
  SourceConfig config;
  config.scheme = self_scheme_;
  config.host = url_.host();
  config.path.clear();
  config.port = url_.IntPort();
  config.host_wildcard = SourceConfig::kNoWildcard;
  config.port_wildcard = SourceConfig::kNoWildcard;
  self_source_.reset(new Source(this, config));
}

void ContentSecurityPolicy::AddPolicyFromHeaderValue(const std::string& header,
                                                     HeaderType type,
                                                     HeaderSource source) {
  // If this is a report-only header inside a <meta> element, bail out.
  if (source == kHeaderSourceMeta && type == kHeaderTypeReport) {
    ReportReportOnlyInMeta(header);
    return;
  }

  base::StringPiece characters(header);

  const char* begin = characters.begin();
  const char* end = characters.end();

  // RFC2616, section 4.2 specifies that headers appearing multiple times can
  // be combined with a comma. Walk the header string, and parse each comma
  // separated chunk as a separate header.
  const char* position = begin;
  while (position < end) {
    SkipUntil(&position, end, ',');

    // header1,header2 OR header1
    //        ^                  ^
    base::StringPiece begin_piece(begin, static_cast<size_t>(position - begin));
    scoped_ptr<DirectiveList> policy(
        new DirectiveList(this, begin_piece, type, source));
    if (type != kHeaderTypeReport && policy->did_set_referrer_policy()) {
      // FIXME: We need a 'ReferrerPolicyUnset' enum to avoid confusing code
      // like this.
      referrer_policy_ = DidSetReferrerPolicy()
                             ? MergeReferrerPolicies(referrer_policy_,
                                                     policy->referrer_policy())
                             : policy->referrer_policy();
    }

    if (!policy->AllowEval(kSuppressReport) &&
        disable_eval_error_message_.empty()) {
      disable_eval_error_message_ = policy->eval_disabled_error_message();
    }

    policies_.push_back(policy.release());

    // Skip the comma, and begin the next header from the current position.
    DCHECK(position == end || *position == ',');
    SkipExactly(&position, end, ',');
    begin = position;
  }
}

}  // namespace csp
}  // namespace cobalt
