/*
 * Copyright (C) 2011 Google, Inc. All rights reserved.
 * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "ContentSecurityPolicyDirectiveList.h"

#include "ContentSecurityPolicyDirectiveNames.h"
#include "Document.h"
#include "Frame.h"
#include "ParsingUtilities.h"
#include "SecurityContext.h"
#include <wtf/text/StringParsingBuffer.h>

namespace WebCore {

template<typename CharacterType> static bool isDirectiveNameCharacter(CharacterType c)
{
    return isASCIIAlphanumeric(c) || c == '-';
}

template<typename CharacterType> static bool isDirectiveValueCharacter(CharacterType c)
{
    return isASCIISpace(c) || (c >= 0x21 && c <= 0x7e); // Whitespace + VCHAR
}

static inline bool checkEval(ContentSecurityPolicySourceListDirective* directive)
{
    return !directive || directive->allowEval();
}

static inline bool checkInline(ContentSecurityPolicySourceListDirective* directive)
{
    return !directive || directive->allowInline();
}

static inline bool checkUnsafeHashes(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash)
{
    return !directive || directive->allowUnsafeHashes(hash);
}

static inline bool checkNonParserInsertedScripts(ContentSecurityPolicySourceListDirective* directive, ParserInserted parserInserted)
{
    if (!directive)
        return true;

    return directive->allowNonParserInsertedScripts() && parserInserted == ParserInserted::No;
}

static inline bool checkSource(ContentSecurityPolicySourceListDirective* directive, const URL& url, bool didReceiveRedirectResponse = false, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone shouldAllowEmptyURLIfSourceListEmpty = ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No)
{
    return !directive || directive->allows(url, didReceiveRedirectResponse, shouldAllowEmptyURLIfSourceListEmpty);
}

static inline bool checkHash(ContentSecurityPolicySourceListDirective* directive, const ContentSecurityPolicyHash& hash)
{
    return !directive || directive->allows(hash);
}

static inline bool checkNonce(ContentSecurityPolicySourceListDirective* directive, const String& nonce)
{
    return !directive || directive->allows(nonce);
}

// Used to compute the comparison URL when checking frame-ancestors. We do this weird conversion so that child
// frames of a page with a unique origin (e.g. about:blank) are not blocked due to their frame-ancestors policy
// and do not need to add the parent's URL to their policy. The latter could allow the child page to be framed
// by anyone. See <https://github.com/w3c/webappsec/issues/311> for more details.
static inline URL urlFromOrigin(const SecurityOrigin& origin)
{
    return { URL { }, origin.toString() };
}

static inline bool checkFrameAncestors(ContentSecurityPolicySourceListDirective* directive, const Frame& frame)
{
    if (!directive)
        return true;
    bool didReceiveRedirectResponse = false;
    for (Frame* current = frame.tree().parent(); current; current = current->tree().parent()) {
        URL origin = urlFromOrigin(current->document()->securityOrigin());
        if (!origin.isValid() || !directive->allows(origin, didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No))
            return false;
    }
    return true;
}

static inline bool checkFrameAncestors(ContentSecurityPolicySourceListDirective* directive, const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins)
{
    if (!directive)
        return true;
    bool didReceiveRedirectResponse = false;
    for (auto& origin : ancestorOrigins) {
        URL originURL = urlFromOrigin(*origin);
        if (!originURL.isValid() || !directive->allows(originURL, didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone::No))
            return false;
    }
    return true;
}

static inline bool checkMediaType(ContentSecurityPolicyMediaListDirective* directive, const String& type, const String& typeAttribute)
{
    if (!directive)
        return true;
    if (typeAttribute.isEmpty() || typeAttribute.stripWhiteSpace() != type)
        return false;
    return directive->allows(type);
}

ContentSecurityPolicyDirectiveList::ContentSecurityPolicyDirectiveList(ContentSecurityPolicy& policy, ContentSecurityPolicyHeaderType type)
    : m_policy(policy)
    , m_headerType(type)
    , m_reportOnly(type == ContentSecurityPolicyHeaderType::Report)
{
}

std::unique_ptr<ContentSecurityPolicyDirectiveList> ContentSecurityPolicyDirectiveList::create(ContentSecurityPolicy& policy, const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicy::PolicyFrom from)
{
    auto directives = makeUnique<ContentSecurityPolicyDirectiveList>(policy, type);
    directives->parse(header, from);

    if (!checkEval(directives->operativeDirective(directives->m_scriptSrc.get()))) {
        directives->setEvalDisabledErrorMessage(makeString("Refused to evaluate a string as JavaScript because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n"));
        directives->setWebAssemblyDisabledErrorMessage(makeString("Refused to create a WebAssembly object because 'unsafe-eval' is not an allowed source of script in the following Content Security Policy directive: \"", directives->operativeDirective(directives->m_scriptSrc.get())->text(), "\".\n"));
    }

    if (directives->isReportOnly() && directives->reportURIs().isEmpty())
        policy.reportMissingReportURI(header);

    return directives;
}

ContentSecurityPolicySourceListDirective* ContentSecurityPolicyDirectiveList::operativeDirective(ContentSecurityPolicySourceListDirective* directive) const
{
    return directive ? directive : m_defaultSrc.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeEval() const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkEval(operativeDirective))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashScript(const ContentSecurityPolicyHash& hash) const
{
    auto* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkUnsafeHashes(operativeDirective, hash))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeHashStyle(const ContentSecurityPolicyHash& hash) const
{
    auto* operativeDirective = this->operativeDirective(m_styleSrc.get());
    if (checkUnsafeHashes(operativeDirective, hash))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeInlineScript() const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkInline(operativeDirective))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForParserInsertedScript(ParserInserted parserInserted) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkNonParserInsertedScripts(operativeDirective, parserInserted))
        return nullptr;

    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForUnsafeInlineStyle() const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
    if (checkInline(operativeDirective))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptHash(const ContentSecurityPolicyHash& hash) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkHash(operativeDirective, hash))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleHash(const ContentSecurityPolicyHash& hash) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
    if (checkHash(operativeDirective, hash))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScriptNonce(const String& nonce) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkNonce(operativeDirective, nonce))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyleNonce(const String& nonce) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
    if (checkNonce(operativeDirective, nonce))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForBaseURI(const URL& url) const
{
    if (checkSource(m_baseURI.get(), url))
        return nullptr;
    return m_baseURI.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForChildContext(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_childSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForConnectSource(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_connectSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFont(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_fontSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFormAction(const URL& url, bool didReceiveRedirectResponse) const
{
    if (checkSource(m_formAction.get(), url, didReceiveRedirectResponse))
        return nullptr;
    return m_formAction.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrame(const URL& url, bool didReceiveRedirectResponse) const
{
    if (url.protocolIsAbout())
        return nullptr;

    // We must enforce the frame-src directive (if specified) before enforcing the child-src directive for a nested browsing
    // context by <https://w3c.github.io/webappsec-csp/2/#directive-child-src-nested> (29 August 2015).
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_frameSrc ? m_frameSrc.get() : m_childSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrameAncestor(const Frame& frame) const
{
    if (checkFrameAncestors(m_frameAncestors.get(), frame))
        return nullptr;
    return m_frameAncestors.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForFrameAncestorOrigins(const Vector<RefPtr<SecurityOrigin>>& ancestorOrigins) const
{
    if (checkFrameAncestors(m_frameAncestors.get(), ancestorOrigins))
        return nullptr;
    return m_frameAncestors.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForImage(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_imgSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

#if ENABLE(APPLICATION_MANIFEST)
const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForManifest(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_manifestSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}
#endif // ENABLE(APPLICATION_MANIFEST)

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForMedia(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_mediaSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForObjectSource(const URL& url, bool didReceiveRedirectResponse, ContentSecurityPolicySourceListDirective::ShouldAllowEmptyURLIfSourceListIsNotNone shouldAllowEmptyURLIfSourceListEmpty) const
{
    if (url.protocolIsAbout())
        return nullptr;
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_objectSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse, shouldAllowEmptyURLIfSourceListEmpty))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForPluginType(const String& type, const String& typeAttribute) const
{
    if (checkMediaType(m_pluginTypes.get(), type, typeAttribute))
        return nullptr;
    return m_pluginTypes.get();
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForScript(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_scriptSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

const ContentSecurityPolicyDirective* ContentSecurityPolicyDirectiveList::violatedDirectiveForStyle(const URL& url, bool didReceiveRedirectResponse) const
{
    ContentSecurityPolicySourceListDirective* operativeDirective = this->operativeDirective(m_styleSrc.get());
    if (checkSource(operativeDirective, url, didReceiveRedirectResponse))
        return nullptr;
    return operativeDirective;
}

// policy            = directive-list
// directive-list    = [ directive *( ";" [ directive ] ) ]
//
void ContentSecurityPolicyDirectiveList::parse(const String& policy, ContentSecurityPolicy::PolicyFrom policyFrom)
{
    m_header = policy;
    if (policy.isEmpty())
        return;

    readCharactersForParsing(policy, [&](auto buffer) {
        while (buffer.hasCharactersRemaining()) {
            auto directiveBegin = buffer.position();
            skipUntil(buffer, ';');

            if (auto directive = parseDirective(StringParsingBuffer { directiveBegin, buffer.position() })) {
                ASSERT(!directive->name.isEmpty());
                if (policyFrom == ContentSecurityPolicy::PolicyFrom::Inherited) {
                    if (equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::upgradeInsecureRequests))
                        continue;
                } else if (policyFrom == ContentSecurityPolicy::PolicyFrom::HTTPEquivMeta) {
                    if (equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::sandbox)
                        || equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::reportURI)
                        || equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::frameAncestors)) {
                        m_policy.reportInvalidDirectiveInHTTPEquivMeta(directive->name);
                        continue;
                    }
                } else if (policyFrom == ContentSecurityPolicy::PolicyFrom::InheritedForPluginDocument) {
                    if (!equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::pluginTypes)
                        && !equalIgnoringASCIICase(directive->name, ContentSecurityPolicyDirectiveNames::reportURI))
                        continue;
                }
                addDirective(WTFMove(*directive));
            }

            ASSERT(buffer.atEnd() || *buffer == ';');
            skipExactly(buffer, ';');
        }
    });
}

// directive         = *WSP [ directive-name [ WSP directive-value ] ]
// directive-name    = 1*( ALPHA / DIGIT / "-" )
// directive-value   = *( WSP / <VCHAR except ";"> )
//
template<typename CharacterType> auto ContentSecurityPolicyDirectiveList::parseDirective(StringParsingBuffer<CharacterType> buffer) -> std::optional<ParsedDirective>
{
    skipWhile<isASCIISpace>(buffer);

    // Empty directive (e.g. ";;;"). Exit early.
    if (buffer.atEnd())
        return std::nullopt;

    auto nameBegin = buffer.position();
    skipWhile<isDirectiveNameCharacter>(buffer);

    // The directive-name must be non-empty.
    if (nameBegin == buffer.position()) {
        skipWhile<isNotASCIISpace>(buffer);
        m_policy.reportUnsupportedDirective(String(nameBegin, buffer.position() - nameBegin));
        return std::nullopt;
    }

    auto name = String(nameBegin, buffer.position() - nameBegin);

    if (buffer.atEnd())
        return ParsedDirective { WTFMove(name), { } };

    if (!skipExactly<isASCIISpace>(buffer)) {
        skipWhile<isNotASCIISpace>(buffer);
        m_policy.reportUnsupportedDirective(String(nameBegin, buffer.position() - nameBegin));
        return std::nullopt;
    }

    skipWhile<isASCIISpace>(buffer);

    auto valueBegin = buffer.position();
    skipWhile<isDirectiveValueCharacter>(buffer);

    if (!buffer.atEnd()) {
        m_policy.reportInvalidDirectiveValueCharacter(name, String(valueBegin, buffer.end() - valueBegin));
        return std::nullopt;
    }

    // The directive-value may be empty.
    if (valueBegin == buffer.position())
        return ParsedDirective { WTFMove(name), { } };

    auto value = String(valueBegin, buffer.position() - valueBegin);
    return ParsedDirective { WTFMove(name), WTFMove(value) };
}

void ContentSecurityPolicyDirectiveList::parseReportURI(ParsedDirective&& directive)
{
    if (!m_reportURIs.isEmpty()) {
        m_policy.reportDuplicateDirective(directive.name);
        return;
    }

    readCharactersForParsing(directive.value, [&](auto buffer) {
        auto begin = buffer.position();
        while (buffer.hasCharactersRemaining()) {
            skipWhile<isASCIISpace>(buffer);

            auto urlBegin = buffer.position();
            skipWhile<isNotASCIISpace>(buffer);

            if (urlBegin < buffer.position())
                m_reportURIs.append(directive.value.substring(urlBegin - begin, buffer.position() - urlBegin));
        }
    });
}


template<class CSPDirectiveType>
void ContentSecurityPolicyDirectiveList::setCSPDirective(ParsedDirective&& directive, std::unique_ptr<CSPDirectiveType>& existingDirective)
{
    if (existingDirective) {
        m_policy.reportDuplicateDirective(directive.name);
        return;
    }
    existingDirective = makeUnique<CSPDirectiveType>(*this, WTFMove(directive.name), WTFMove(directive.value));
}

void ContentSecurityPolicyDirectiveList::applySandboxPolicy(ParsedDirective&& directive)
{
    if (m_reportOnly) {
        m_policy.reportInvalidDirectiveInReportOnlyMode(directive.name);
        return;
    }
    if (m_haveSandboxPolicy) {
        m_policy.reportDuplicateDirective(directive.name);
        return;
    }
    m_haveSandboxPolicy = true;
    String invalidTokens;
    m_policy.enforceSandboxFlags(SecurityContext::parseSandboxPolicy(WTFMove(directive.value), invalidTokens));
    if (!invalidTokens.isNull())
        m_policy.reportInvalidSandboxFlags(invalidTokens);
}

void ContentSecurityPolicyDirectiveList::setUpgradeInsecureRequests(ParsedDirective&& directive)
{
    if (m_reportOnly) {
        m_policy.reportInvalidDirectiveInReportOnlyMode(WTFMove(directive.name));
        return;
    }
    if (m_upgradeInsecureRequests) {
        m_policy.reportDuplicateDirective(WTFMove(directive.name));
        return;
    }
    m_upgradeInsecureRequests = true;
    m_policy.setUpgradeInsecureRequests(true);
}

void ContentSecurityPolicyDirectiveList::setBlockAllMixedContentEnabled(ParsedDirective&& directive)
{
    if (m_hasBlockAllMixedContentDirective) {
        m_policy.reportDuplicateDirective(WTFMove(directive.name));
        return;
    }
    m_hasBlockAllMixedContentDirective = true;
}

void ContentSecurityPolicyDirectiveList::addDirective(ParsedDirective&& directive)
{
    ASSERT(!directive.name.isEmpty());

    if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::defaultSrc)) {
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_defaultSrc);
        m_policy.addHashAlgorithmsForInlineScripts(m_defaultSrc->hashAlgorithmsUsed());
        m_policy.addHashAlgorithmsForInlineStylesheets(m_defaultSrc->hashAlgorithmsUsed());
    } else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::scriptSrc)) {
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_scriptSrc);
        m_policy.addHashAlgorithmsForInlineScripts(m_scriptSrc->hashAlgorithmsUsed());
    } else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::styleSrc)) {
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_styleSrc);
        m_policy.addHashAlgorithmsForInlineStylesheets(m_styleSrc->hashAlgorithmsUsed());
    } else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::objectSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_objectSrc);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::frameSrc)) {
        // FIXME: Log to console "The frame-src directive is deprecated. Use the child-src directive instead."
        // See <https://bugs.webkit.org/show_bug.cgi?id=155773>.
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_frameSrc);
    } else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::imgSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_imgSrc);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::fontSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_fontSrc);
#if ENABLE(APPLICATION_MANIFEST)
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::manifestSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_manifestSrc);
#endif
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::mediaSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_mediaSrc);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::connectSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_connectSrc);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::childSrc))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_childSrc);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::formAction))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_formAction);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::baseURI))
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_baseURI);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::frameAncestors)) {
        if (m_reportOnly) {
            m_policy.reportInvalidDirectiveInReportOnlyMode(directive.name);
            return;
        }
        setCSPDirective<ContentSecurityPolicySourceListDirective>(WTFMove(directive), m_frameAncestors);
    } else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::pluginTypes))
        setCSPDirective<ContentSecurityPolicyMediaListDirective>(WTFMove(directive), m_pluginTypes);
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::sandbox))
        applySandboxPolicy(WTFMove(directive));
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::reportURI))
        parseReportURI(WTFMove(directive));
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::upgradeInsecureRequests))
        setUpgradeInsecureRequests(WTFMove(directive));
    else if (equalIgnoringASCIICase(directive.name, ContentSecurityPolicyDirectiveNames::blockAllMixedContent))
        setBlockAllMixedContentEnabled(WTFMove(directive));
    else
        m_policy.reportUnsupportedDirective(WTFMove(directive.name));
}

bool ContentSecurityPolicyDirectiveList::strictDynamicIncluded()
{
    ContentSecurityPolicySourceListDirective* directive = this->operativeDirective(m_scriptSrc.get());
    return directive && directive->allowNonParserInsertedScripts();
}

} // namespace WebCore
