// 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/directive_list.h"

#include "base/base64.h"
#include "base/stringprintf.h"
#include "cobalt/csp/crypto.h"
#include "cobalt/csp/media_list_directive.h"
#include "cobalt/csp/source_list_directive.h"

namespace cobalt {
namespace csp {

namespace {

std::string GetSha256String(const std::string& content) {
  DigestValue digest;
  if (!ComputeDigest(kHashAlgorithmSha256, content.c_str(), content.length(),
                     &digest) ||
      digest.size() == 0) {
    return "sha256-...";
  }

  base::StringPiece digest_piece(reinterpret_cast<char*>(&digest[0]),
                                 digest.size());
  std::string encoded;
  bool ok = base::Base64Encode(digest_piece, &encoded);
  if (ok) {
    return "sha256-" + encoded;
  } else {
    DLOG(WARNING) << "Base64Encode failed on " << content;
    return "sha256-...";
  }
}

std::string ElidedUrl(const GURL& url) {
  // Emulate KURL::elidedString() in Blink.

  std::string url_spec = url.spec();
  const size_t len = url_spec.length();
  if (len < 1024) {
    return url_spec;
  } else {
    return url_spec.substr(0, 511) + "..." + url_spec.substr(len - 510, 510);
  }
}
}  // namespace

DirectiveList::DirectiveList(ContentSecurityPolicy* policy,
                             const base::StringPiece& text, HeaderType type,
                             HeaderSource source)
    : policy_(policy),
      header_type_(type),
      header_source_(source),
      report_only_(type == kHeaderTypeReport),
      has_sandbox_policy_(false),
      has_suborigin_policy_(false),
      reflected_xss_disposition_(kReflectedXSSUnset),
      did_set_referrer_policy_(false),
      referrer_policy_(kReferrerPolicyDefault),
      strict_mixed_content_checking_enforced_(false),
      upgrade_insecure_requests_(false) {
  Parse(text);
  if (!CheckEval(OperativeDirective(script_src_.get()))) {
    std::string message =
        "Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
        "not an allowed source of script in the following Content Security "
        "Policy directive: \"" +
        OperativeDirective(script_src_.get())->text() + "\".\n";
    set_eval_disabled_error_message(message);
  }
  if (report_only() && report_endpoints_.empty()) {
    policy->ReportMissingReportURI(text.as_string());
  }
}

DirectiveList::~DirectiveList() {}

void DirectiveList::ReportViolation(const std::string& directive_text,
                                    const std::string& effective_directive,
                                    const std::string& console_message,
                                    const GURL& blocked_url) const {
  std::string message =
      report_only_ ? "[Report Only] " + console_message : console_message;
  policy_->ReportViolation(directive_text, effective_directive, message,
                           blocked_url, report_endpoints_, header_);
}

void DirectiveList::ReportViolationWithLocation(
    const std::string& directive_text, const std::string& effective_directive,
    const std::string& console_message, const GURL& blocked_url,
    const std::string& context_url, int context_line) const {
  std::string message = base::StringPrintf(
      "%s%s %s:%d", report_only_ ? "[Report Only] " : "",
      console_message.c_str(), context_url.c_str(), context_line);
  policy_->ReportViolation(directive_text, effective_directive, message,
                           blocked_url, report_endpoints_, header_);
}

bool DirectiveList::CheckEval(SourceListDirective* directive) const {
  return !directive || directive->AllowEval();
}

bool DirectiveList::CheckInline(SourceListDirective* directive) const {
  return !directive ||
         (directive->AllowInline() && !directive->hash_or_nonce_present());
}

bool DirectiveList::CheckNonce(SourceListDirective* directive,
                               const std::string& nonce) const {
  return !directive || directive->AllowNonce(nonce);
}

bool DirectiveList::CheckHash(SourceListDirective* directive,
                              const HashValue& hashValue) const {
  return !directive || directive->AllowHash(hashValue);
}

bool DirectiveList::CheckSource(
    SourceListDirective* directive, const GURL& url,
    ContentSecurityPolicy::RedirectStatus redirect_status) const {
  return !directive || directive->Allows(url, redirect_status);
}

bool DirectiveList::CheckMediaType(MediaListDirective* directive,
                                   const std::string& type,
                                   const std::string& type_attribute) const {
  if (!directive) {
    return true;
  }
  std::string trimmed_type_attribute;
  TrimWhitespaceASCII(type_attribute, TRIM_ALL, &trimmed_type_attribute);

  if (type_attribute.empty() || trimmed_type_attribute != type) {
    return false;
  }
  return directive->Allows(type);
}

SourceListDirective* DirectiveList::OperativeDirective(
    SourceListDirective* directive) const {
  return directive ? directive : default_src_.get();
}

SourceListDirective* DirectiveList::OperativeDirective(
    SourceListDirective* directive,
    SourceListDirective* directive_override) const {
  return directive ? directive : directive_override;
}

bool DirectiveList::CheckEvalAndReportViolation(
    SourceListDirective* directive, const std::string& console_message) const {
  if (CheckEval(directive)) {
    return true;
  }

  std::string suffix;
  if (directive == default_src_) {
    suffix =
        " Note that 'script-src' was not explicitly set, so 'default-src' is "
        "used as a fallback.";
  }

  ReportViolation(
      directive->text(), ContentSecurityPolicy::kScriptSrc,
      console_message + "\"" + directive->text() + "\"." + suffix + "\n",
      GURL());
  if (report_only_) {
    return true;
  } else {
    return false;
  }
}

bool DirectiveList::CheckMediaTypeAndReportViolation(
    MediaListDirective* directive, const std::string& type,
    const std::string& type_attribute,
    const std::string& console_message) const {
  if (CheckMediaType(directive, type, type_attribute)) {
    return true;
  }

  std::string message = console_message + "\'" + directive->text() + "\'.";
  if (type_attribute.empty()) {
    message +=
        " When enforcing the 'plugin-types' directive, the plugin's "
        "media type must be explicitly declared with a 'type' attribute "
        "on the containing element (e.g. '<object type=\"[TYPE GOES "
        "HERE]\" ...>').";
  }

  ReportViolation(directive->text(), ContentSecurityPolicy::kPluginTypes,
                  message + "\n", GURL());
  return deny_if_enforcing_policy();
}

bool DirectiveList::CheckInlineAndReportViolation(
    SourceListDirective* directive, const std::string& console_message,
    const std::string& context_url, int context_line, bool is_script,
    const std::string& hash_value) const {
  if (CheckInline(directive)) {
    return true;
  }

  std::string suffix;
  if (directive->AllowInline() && directive->hash_or_nonce_present()) {
    // If inline is allowed, but a hash or nonce is present, we ignore
    // 'unsafe-inline'. Throw a reasonable error.
    suffix =
        " Note that 'unsafe-inline' is ignored if either a hash or nonce value "
        "is present in the source list.";
  } else {
    suffix =
        " Either the 'unsafe-inline' keyword, a hash ('" + hash_value +
        "'), or a nonce ('nonce-...') is required to enable inline execution.";
    if (directive == default_src_)
      suffix = suffix + " Note also that '" +
               std::string(is_script ? "script" : "style") +
               "-src' was not explicitly set, so 'default-src' is used as a "
               "fallback.";
  }

  ReportViolationWithLocation(
      directive->text(), is_script ? ContentSecurityPolicy::kScriptSrc
                                   : ContentSecurityPolicy::kStyleSrc,
      console_message + "\"" + directive->text() + "\"." + suffix + "\n",
      GURL(), context_url, context_line);

  if (!report_only_) {
    if (is_script) {
      // policy_->ReportBlockedScriptExecutionToInspector(directive->text());
    }
    return false;
  }
  return true;
}

bool DirectiveList::CheckSourceAndReportViolation(
    SourceListDirective* directive, const GURL& url,
    const std::string& effective_directive,
    ContentSecurityPolicy::RedirectStatus redirect_status) const {
  if (CheckSource(directive, url, redirect_status)) {
    return true;
  }

  std::string prefix;
  if (ContentSecurityPolicy::kBaseURI == effective_directive) {
    prefix = "Refused to set the document's base URI to '";
  } else if (ContentSecurityPolicy::kChildSrc == effective_directive) {
    prefix = "Refused to create a child context containing '";
  } else if (ContentSecurityPolicy::kConnectSrc == effective_directive) {
    prefix = "Refused to connect to '";
  } else if (ContentSecurityPolicy::kFontSrc == effective_directive) {
    prefix = "Refused to load the font '";
  } else if (ContentSecurityPolicy::kFormAction == effective_directive) {
    prefix = "Refused to send form data to '";
  } else if (ContentSecurityPolicy::kFrameSrc == effective_directive) {
    prefix = "Refused to frame '";
  } else if (ContentSecurityPolicy::kImgSrc == effective_directive) {
    prefix = "Refused to load the image '";
  } else if (ContentSecurityPolicy::kLocationSrc == effective_directive) {
    prefix = "Refused to navigate to '";
  } else if (ContentSecurityPolicy::kMediaSrc == effective_directive) {
    prefix = "Refused to load media from '";
  } else if (ContentSecurityPolicy::kManifestSrc == effective_directive) {
    prefix = "Refused to load manifest from '";
  } else if (ContentSecurityPolicy::kObjectSrc == effective_directive) {
    prefix = "Refused to load plugin data from '";
  } else if (ContentSecurityPolicy::kScriptSrc == effective_directive) {
    prefix = "Refused to load the script '";
  } else if (ContentSecurityPolicy::kStyleSrc == effective_directive) {
    prefix = "Refused to load the stylesheet '";
  }

  std::string suffix = std::string();
  if (directive == default_src_)
    suffix =
        " Note that '" + effective_directive +
        "' was not explicitly set, so 'default-src' is used as a fallback.";

  ReportViolation(directive->text(), effective_directive,
                  prefix + ElidedUrl(url) +
                      "' because it violates the following Content Security "
                      "Policy directive: \"" +
                      directive->text() + "\"." + suffix + "\n",
                  url);
  return deny_if_enforcing_policy();
}

bool DirectiveList::AllowJavaScriptURLs(
    const std::string& context_url, int context_line,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  if (reporting_status == ContentSecurityPolicy::kSendReport) {
    return CheckInlineAndReportViolation(
        OperativeDirective(script_src_.get()),
        "Refused to execute JavaScript URL because it violates the following "
        "Content Security Policy directive: ",
        context_url, context_line, true, "sha256-...");
  }
  return CheckInline(OperativeDirective(script_src_.get()));
}

bool DirectiveList::AllowInlineEventHandlers(
    const std::string& context_url, int context_line,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  if (reporting_status == ContentSecurityPolicy::kSendReport) {
    return CheckInlineAndReportViolation(
        OperativeDirective(script_src_.get()),
        "Refused to execute inline event handler because it violates the "
        "following Content Security Policy directive: ",
        context_url, context_line, true, "sha256-...");
  }
  return CheckInline(OperativeDirective(script_src_.get()));
}

bool DirectiveList::AllowInlineScript(
    const std::string& context_url, int context_line,
    ContentSecurityPolicy::ReportingStatus reporting_status,
    const std::string& content) const {
  if (reporting_status == ContentSecurityPolicy::kSendReport) {
    return CheckInlineAndReportViolation(
        OperativeDirective(script_src_.get()),
        "Refused to execute inline script because it violates the following "
        "Content Security Policy directive: ",
        context_url, context_line, true, GetSha256String(content));
  }
  return CheckInline(OperativeDirective(script_src_.get()));
}

bool DirectiveList::AllowInlineStyle(
    const std::string& context_url, int context_line,
    ContentSecurityPolicy::ReportingStatus reporting_status,
    const std::string& content) const {
  if (reporting_status == ContentSecurityPolicy::kSendReport) {
    return CheckInlineAndReportViolation(
        OperativeDirective(style_src_.get()),
        "Refused to apply inline style because it violates the following "
        "Content Security Policy directive: ",
        context_url, context_line, false, GetSha256String(content));
  }
  return CheckInline(OperativeDirective(style_src_.get()));
}

bool DirectiveList::AllowEval(
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  if (reporting_status == ContentSecurityPolicy::kSendReport) {
    return CheckEvalAndReportViolation(
        OperativeDirective(script_src_.get()),
        "Refused to evaluate a string as JavaScript because 'unsafe-eval' is "
        "not an allowed source of script in the following Content Security "
        "Policy directive: ");
  }
  return CheckEval(OperativeDirective(script_src_.get()));
}

bool DirectiveList::AllowScriptFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(script_src_.get()), url,
                   ContentSecurityPolicy::kScriptSrc, redirect_status)
             : CheckSource(OperativeDirective(script_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowObjectFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(object_src_.get()), url,
                   ContentSecurityPolicy::kObjectSrc, redirect_status)
             : CheckSource(OperativeDirective(object_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowImageFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(img_src_.get()), url,
                   ContentSecurityPolicy::kImgSrc, redirect_status)
             : CheckSource(OperativeDirective(img_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowStyleFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(style_src_.get()), url,
                   ContentSecurityPolicy::kStyleSrc, redirect_status)
             : CheckSource(OperativeDirective(style_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowFontFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(font_src_.get()), url,
                   ContentSecurityPolicy::kFontSrc, redirect_status)
             : CheckSource(OperativeDirective(font_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowMediaFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(media_src_.get()), url,
                   ContentSecurityPolicy::kMediaSrc, redirect_status)
             : CheckSource(OperativeDirective(media_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowManifestFromSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(manifest_src_.get()), url,
                   ContentSecurityPolicy::kManifestSrc, redirect_status)
             : CheckSource(OperativeDirective(manifest_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowConnectToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   OperativeDirective(connect_src_.get()), url,
                   ContentSecurityPolicy::kConnectSrc, redirect_status)
             : CheckSource(OperativeDirective(connect_src_.get()), url,
                           redirect_status);
}

bool DirectiveList::AllowNavigateToSource(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  // No fallback to default for h5vcc-location-src policy, so we don't use
  // OperativeDirective() in this case.
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(
                   location_src_.get(), url,
                   ContentSecurityPolicy::kLocationSrc, redirect_status)
             : CheckSource(location_src_.get(), url, redirect_status);
}

bool DirectiveList::AllowFormAction(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(form_action_.get(), url,
                                             ContentSecurityPolicy::kFormAction,
                                             redirect_status)
             : CheckSource(form_action_.get(), url, redirect_status);
}

bool DirectiveList::AllowBaseURI(
    const GURL& url, ContentSecurityPolicy::RedirectStatus redirect_status,
    ContentSecurityPolicy::ReportingStatus reporting_status) const {
  return reporting_status == ContentSecurityPolicy::kSendReport
             ? CheckSourceAndReportViolation(base_uri_.get(), url,
                                             ContentSecurityPolicy::kBaseURI,
                                             redirect_status)
             : CheckSource(base_uri_.get(), url, redirect_status);
}

bool DirectiveList::AllowScriptNonce(const std::string& nonce) const {
  return CheckNonce(OperativeDirective(script_src_.get()), nonce);
}

bool DirectiveList::AllowStyleNonce(const std::string& nonce) const {
  return CheckNonce(OperativeDirective(style_src_.get()), nonce);
}

bool DirectiveList::AllowScriptHash(const HashValue& hash_value) const {
  return CheckHash(OperativeDirective(script_src_.get()), hash_value);
}

bool DirectiveList::AllowStyleHash(const HashValue& hash_value) const {
  return CheckHash(OperativeDirective(style_src_.get()), hash_value);
}

const std::string& DirectiveList::PluginTypesText() const {
  DCHECK_EQ(has_plugin_types(), true);
  return plugin_types_->text();
}

// policy            = directive-list
// directive-list    = [ directive *( ";" [ directive ] ) ]
//
void DirectiveList::Parse(const base::StringPiece& text) {
  const char* begin = text.begin();
  const char* end = text.end();
  header_ = ToString(begin, end);

  if (begin == end) {
    return;
  }

  const char* position = begin;
  while (position < end) {
    const char* directive_begin = position;
    SkipUntil(&position, end, ';');

    std::string name, value;
    if (ParseDirective(directive_begin, position, &name, &value)) {
      DCHECK(!name.empty());
      AddDirective(name, value);
    }

    DCHECK(position == end || *position == ';');
    SkipExactly(&position, end, ';');
  }
}

// directive         = *WSP [ directive-name [ WSP directive-value ] ]
// directive-name    = 1*( ALPHA / DIGIT / "-" )
// directive-value   = *( WSP / <VCHAR except ";"> )
//
bool DirectiveList::ParseDirective(const char* begin, const char* end,
                                   std::string* name, std::string* value) {
  DCHECK(name && name->empty());
  DCHECK(value && value->empty());

  const char* position = begin;
  SkipWhile<IsAsciiWhitespace>(&position, end);

  // Empty directive (e.g. ";;;"). Exit early.
  if (position == end) {
    return false;
  }

  const char* name_begin = position;
  SkipWhile<IsCSPDirectiveNameCharacter>(&position, end);

  // The directive-name must be non-empty.
  if (name_begin == position) {
    SkipWhile<IsNotAsciiWhitespace>(&position, end);
    policy_->ReportUnsupportedDirective(ToString(name_begin, position));
    return false;
  }

  *name = ToString(name_begin, position);

  if (position == end) {
    return true;
  }

  if (!SkipExactly<IsAsciiWhitespace>(&position, end)) {
    SkipWhile<IsNotAsciiWhitespace>(&position, end);
    policy_->ReportUnsupportedDirective(ToString(name_begin, position));
    return false;
  }

  SkipWhile<IsAsciiWhitespace>(&position, end);

  const char* value_begin = position;
  SkipWhile<IsCSPDirectiveValueCharacter>(&position, end);

  if (position != end) {
    policy_->ReportInvalidDirectiveValueCharacter(*name,
                                                  ToString(value_begin, end));
    return false;
  }

  // The directive-value may be empty.
  if (value_begin == position) {
    return true;
  }

  *value = ToString(value_begin, position);
  return true;
}

void DirectiveList::ParseReportURI(const std::string& name,
                                   const std::string& value) {
  if (header_source_ == kHeaderSourceMeta) {
    // The report-uri, frame-ancestors, and sandbox directives are not supported
    // inside a meta element.
    // https://w3c.github.io/webappsec-csp/#meta-element
    policy_->ReportDirectiveNotSupportedInsideMeta(name);
    return;
  }
  if (!report_endpoints_.empty()) {
    policy_->ReportDuplicateDirective(name);
    return;
  }

  base::StringPiece characters(value);
  const char* position = characters.data();
  const char* end = position + characters.size();

  while (position < end) {
    SkipWhile<IsAsciiWhitespace>(&position, end);

    const char* url_begin = position;
    SkipWhile<IsNotAsciiWhitespace>(&position, end);

    if (url_begin < position) {
      std::string url = ToString(url_begin, position);
      report_endpoints_.push_back(url);
    }
  }
}

void DirectiveList::SetCSPDirective(
    const std::string& name, const std::string& value,
    scoped_ptr<SourceListDirective>* directive) {
  DCHECK(directive);
  if (*directive) {
    policy_->ReportDuplicateDirective(name);
    return;
  }
  directive->reset(new SourceListDirective(name, value, policy_));
}

void DirectiveList::SetCSPDirective(const std::string& name,
                                    const std::string& value,
                                    scoped_ptr<MediaListDirective>* directive) {
  DCHECK(directive);
  if (*directive) {
    policy_->ReportDuplicateDirective(name);
    return;
  }
  directive->reset(new MediaListDirective(name, value, policy_));
}

void DirectiveList::EnforceStrictMixedContentChecking(
    const std::string& name, const std::string& value) {
  if (report_only_) {
    policy_->ReportInvalidInReportOnly(name);
    return;
  }
  if (strict_mixed_content_checking_enforced_) {
    policy_->ReportDuplicateDirective(name);
    return;
  }
  strict_mixed_content_checking_enforced_ = true;
  policy_->set_enforce_strict_mixed_content_checking();
  if (!value.empty()) {
    policy_->ReportValueForEmptyDirective(name, value);
  }
}

void DirectiveList::EnableInsecureRequestsUpgrade(const std::string& name,
                                                  const std::string& value) {
  if (report_only_) {
    policy_->ReportInvalidInReportOnly(name);
    return;
  }
  if (upgrade_insecure_requests_) {
    policy_->ReportDuplicateDirective(name);
    return;
  }
  upgrade_insecure_requests_ = true;

  // TODO: Do something with this.
  NOTIMPLEMENTED() << "SetInsecureRequestsPolicy()";

  if (!value.empty()) {
    policy_->ReportValueForEmptyDirective(name, value);
  }
}

void DirectiveList::ParseReflectedXSS(const std::string& name,
                                      const std::string& value) {
  if (reflected_xss_disposition_ != kReflectedXSSUnset) {
    policy_->ReportDuplicateDirective(name);
    reflected_xss_disposition_ = kReflectedXSSInvalid;
    return;
  }

  if (value.empty()) {
    reflected_xss_disposition_ = kReflectedXSSInvalid;
    policy_->ReportInvalidReflectedXSS(value);
    return;
  }

  base::StringPiece characters(value);
  const char* position = characters.data();
  const char* end = position + characters.size();

  SkipWhile<IsAsciiWhitespace>(&position, end);
  const char* begin = position;
  SkipWhile<IsNotAsciiWhitespace>(&position, end);

  // value1
  //       ^

  if (LowerCaseEqualsASCII(begin, position, "allow")) {
    reflected_xss_disposition_ = kAllowReflectedXSS;
  } else if (LowerCaseEqualsASCII(begin, position, "filter")) {
    reflected_xss_disposition_ = kFilterReflectedXSS;
  } else if (LowerCaseEqualsASCII(begin, position, "block")) {
    reflected_xss_disposition_ = kBlockReflectedXSS;
  } else {
    reflected_xss_disposition_ = kReflectedXSSInvalid;
    policy_->ReportInvalidReflectedXSS(value);
    return;
  }

  SkipWhile<IsAsciiWhitespace>(&position, end);
  if (position == end && reflected_xss_disposition_ != kReflectedXSSUnset) {
    return;
  }

  // value1 value2
  //        ^
  reflected_xss_disposition_ = kReflectedXSSInvalid;
  policy_->ReportInvalidReflectedXSS(value);
}

void DirectiveList::ParseReferrer(const std::string& name,
                                  const std::string& value) {
  if (did_set_referrer_policy_) {
    policy_->ReportDuplicateDirective(name);
    referrer_policy_ = kReferrerPolicyNoReferrer;
    return;
  }

  did_set_referrer_policy_ = true;

  if (value.empty()) {
    policy_->ReportInvalidReferrer(value);
    referrer_policy_ = kReferrerPolicyNoReferrer;
    return;
  }

  base::StringPiece characters(value);

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

  SkipWhile<IsAsciiWhitespace>(&position, end);
  const char* begin = position;
  SkipWhile<IsNotAsciiWhitespace>(&position, end);

  // value1
  //       ^
  if (LowerCaseEqualsASCII(begin, position, "unsafe-url")) {
    referrer_policy_ = kReferrerPolicyUnsafeUrl;
  } else if (LowerCaseEqualsASCII(begin, position, "no-referrer")) {
    referrer_policy_ = kReferrerPolicyNoReferrer;
  } else if (LowerCaseEqualsASCII(begin, position,
                                  "no-referrer-when-downgrade")) {
    referrer_policy_ = kReferrerPolicyDefault;
  } else if (LowerCaseEqualsASCII(begin, position, "origin")) {
    referrer_policy_ = kReferrerPolicyOrigin;
  } else if (LowerCaseEqualsASCII(begin, position,
                                  "origin-when-cross-origin") ||
             LowerCaseEqualsASCII(begin, position, "origin-when-crossorigin")) {
    referrer_policy_ = kReferrerPolicyOriginWhenCrossOrigin;
  } else {
    policy_->ReportInvalidReferrer(value);
    return;
  }

  SkipWhile<IsAsciiWhitespace>(&position, end);
  if (position == end) {
    return;
  }

  // value1 value2
  //        ^
  referrer_policy_ = kReferrerPolicyNoReferrer;
  policy_->ReportInvalidReferrer(value);
}

std::string DirectiveList::ParseSuboriginName(const std::string& policy) {
  base::StringPiece characters(policy);

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

  // Parse the name of the suborigin (no spaces, single string)
  SkipWhile<IsAsciiWhitespace>(&position, end);
  if (position == end) {
    policy_->ReportInvalidSuboriginFlags("No suborigin name specified.");
    return std::string();
  }

  const char* begin = position;

  SkipWhile<IsAsciiAlphanumeric>(&position, end);
  if (position != end && !IsAsciiWhitespace(*position)) {
    policy_->ReportInvalidSuboriginFlags(
        "Invalid character \'" + std::string(position, 1) + "\' in suborigin.");
    return std::string();
  }
  size_t length = static_cast<size_t>(position - begin);
  SkipWhile<IsAsciiWhitespace>(&position, end);
  if (position != end) {
    policy_->ReportInvalidSuboriginFlags(
        "Whitespace is not allowed in suborigin names.");
    return std::string();
  }

  return std::string(begin, length);
}

void DirectiveList::AddDirective(const std::string& name,
                                 const std::string& value) {
  DCHECK(!name.empty());
  std::string lower_name = StringToLowerASCII(name);
  if (lower_name == ContentSecurityPolicy::kDefaultSrc) {
    SetCSPDirective(name, value, &default_src_);
  } else if (lower_name == ContentSecurityPolicy::kScriptSrc) {
    SetCSPDirective(name, value, &script_src_);
    policy_->set_uses_script_hash_algorithms(
        script_src_->hash_algorithms_used());
  } else if (lower_name == ContentSecurityPolicy::kObjectSrc) {
    SetCSPDirective(name, value, &object_src_);
  } else if (lower_name == ContentSecurityPolicy::kFrameAncestors) {
    SetCSPDirective(name, value, &frame_ancestors_);
  } else if (lower_name == ContentSecurityPolicy::kFrameSrc) {
    SetCSPDirective(name, value, &frame_src_);
  } else if (lower_name == ContentSecurityPolicy::kImgSrc) {
    SetCSPDirective(name, value, &img_src_);
  } else if (lower_name == ContentSecurityPolicy::kStyleSrc) {
    SetCSPDirective(name, value, &style_src_);
    policy_->set_uses_style_hash_algorithms(style_src_->hash_algorithms_used());
  } else if (lower_name == ContentSecurityPolicy::kFontSrc) {
    SetCSPDirective(name, value, &font_src_);
  } else if (lower_name == ContentSecurityPolicy::kLocationSrc) {
    SetCSPDirective(name, value, &location_src_);
  } else if (lower_name == ContentSecurityPolicy::kMediaSrc) {
    SetCSPDirective(name, value, &media_src_);
  } else if (lower_name == ContentSecurityPolicy::kConnectSrc) {
    SetCSPDirective(name, value, &connect_src_);
  } else if (lower_name == ContentSecurityPolicy::kSandbox) {
    // TODO: ApplySandboxPolicy().
    // ApplySandboxPolicy(name, value);
    NOTIMPLEMENTED() << ContentSecurityPolicy::kSandbox;
  } else if (lower_name == ContentSecurityPolicy::kReportURI) {
    ParseReportURI(name, value);
  } else if (lower_name == ContentSecurityPolicy::kBaseURI) {
    SetCSPDirective(name, value, &base_uri_);
  } else if (lower_name == ContentSecurityPolicy::kChildSrc) {
    SetCSPDirective(name, value, &child_src_);
  } else if (lower_name == ContentSecurityPolicy::kFormAction) {
    SetCSPDirective(name, value, &form_action_);
  } else if (lower_name == ContentSecurityPolicy::kPluginTypes) {
    SetCSPDirective(name, value, &plugin_types_);
  } else if (lower_name == ContentSecurityPolicy::kReflectedXSS) {
    ParseReflectedXSS(name, value);
  } else if (lower_name == ContentSecurityPolicy::kReferrer) {
    ParseReferrer(name, value);
  } else if (lower_name == ContentSecurityPolicy::kUpgradeInsecureRequests) {
    EnableInsecureRequestsUpgrade(name, value);
  } else if (lower_name == ContentSecurityPolicy::kBlockAllMixedContent) {
    EnforceStrictMixedContentChecking(name, value);
  } else if (lower_name == ContentSecurityPolicy::kManifestSrc) {
    SetCSPDirective(name, value, &manifest_src_);
  } else if (lower_name == ContentSecurityPolicy::kSuborigin) {
    // TODO: ApplySuboriginPolicy.
    // ApplySuboriginPolicy(name, value);
    NOTIMPLEMENTED() << ContentSecurityPolicy::kSuborigin;
  } else {
    policy_->ReportUnsupportedDirective(name);
  }
}

}  // namespace csp
}  // namespace cobalt
