/*
 * 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
