CSP: Simplify logic for checking policies
authordbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Mar 2016 02:41:28 +0000 (02:41 +0000)
committerdbates@webkit.org <dbates@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 24 Mar 2016 02:41:28 +0000 (02:41 +0000)
https://bugs.webkit.org/show_bug.cgi?id=155817
<rdar://problem/25326546>

Reviewed by Zalan Bujtas.

Consolidate the various static template functions into a single function called ContentSecurityPolicy::allPoliciesAllow()
that tests whether a resource request when evaluated with respect to a directive (given as a ContentSecurityPolicyDirectiveList
pointer-to-member function) violates any of the CSPs that were delivered with the document.

No functionality changed. So, no new tests.

* page/csp/ContentSecurityPolicy.cpp:
(WebCore::ContentSecurityPolicy::allPoliciesAllowHashFromContent): Formerly name isAllowedByAllWithHash. Made it
a member function so that we query for the document encoding instead of taking it as an argument. Modified
it to take a predicate function to pass it to allPoliciesAllow().
(WebCore::ContentSecurityPolicy::allowJavaScriptURLs): Modified to use ContentSecurityPolicy::allPoliciesAllow().
(WebCore::ContentSecurityPolicy::allowInlineEventHandlers): Ditto.
(WebCore::ContentSecurityPolicy::allowScriptWithNonce): Ditto.
(WebCore::ContentSecurityPolicy::allowStyleWithNonce): Ditto.
(WebCore::ContentSecurityPolicy::allowInlineScript): Modified to use ContentSecurityPolicy::allPoliciesAllow() and
ContentSecurityPolicy::allPoliciesAllowHashFromContent().
(WebCore::ContentSecurityPolicy::allowInlineStyle): Ditto.
(WebCore::ContentSecurityPolicy::allowEval): Modified to use ContentSecurityPolicy::allPoliciesAllow().
(WebCore::ContentSecurityPolicy::allowFrameAncestors): Ditto.
(WebCore::ContentSecurityPolicy::allowPluginType): Ditto.
(WebCore::ContentSecurityPolicy::allowScriptFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowObjectFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowChildFrameFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowChildContextFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowImageFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowStyleFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowFontFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowMediaFromSource): Ditto.
(WebCore::ContentSecurityPolicy::allowConnectToSource): Ditto.
(WebCore::ContentSecurityPolicy::allowFormAction): Ditto.
(WebCore::ContentSecurityPolicy::allowBaseURI): Ditto.
(WebCore::isAllowedByAllWithFrame): Deleted.
(WebCore::isAllowedByAll): Deleted.
(WebCore::isAllowedByAllWithState): Deleted.
(WebCore::isAllowedByAllWithContext): Deleted.
(WebCore::isAllowedByAllWithNonce): Deleted.
(WebCore::isAllowedByAllWithHash): Deleted.
(WebCore::isAllowedByAllWithHashFromContent): Deleted.
(WebCore::isAllowedByAllWithURL): Deleted.
(WebCore::ContentSecurityPolicy::documentEncoding): Deleted. Incorporated its functionality into ContentSecurityPolicy::allPoliciesAllowHashFromContent().
(WebCore::ContentSecurityPolicy::isActive): Deleted. This function has been unused since the removal of the CSP script
interface in <http://trac.webkit.org/changeset/197142>.
* page/csp/ContentSecurityPolicy.h:
(WebCore::ContentSecurityPolicy::allPoliciesAllow): Added. Returns whether the predicate function evaluates to true
for all CSP policies.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@198613 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/page/csp/ContentSecurityPolicy.cpp
Source/WebCore/page/csp/ContentSecurityPolicy.h

index 384a00d..19da004 100644 (file)
@@ -1,3 +1,57 @@
+2016-03-23  Daniel Bates  <dabates@apple.com>
+
+        CSP: Simplify logic for checking policies
+        https://bugs.webkit.org/show_bug.cgi?id=155817
+        <rdar://problem/25326546>
+
+        Reviewed by Zalan Bujtas.
+
+        Consolidate the various static template functions into a single function called ContentSecurityPolicy::allPoliciesAllow()
+        that tests whether a resource request when evaluated with respect to a directive (given as a ContentSecurityPolicyDirectiveList
+        pointer-to-member function) violates any of the CSPs that were delivered with the document.
+
+        No functionality changed. So, no new tests.
+
+        * page/csp/ContentSecurityPolicy.cpp:
+        (WebCore::ContentSecurityPolicy::allPoliciesAllowHashFromContent): Formerly name isAllowedByAllWithHash. Made it
+        a member function so that we query for the document encoding instead of taking it as an argument. Modified
+        it to take a predicate function to pass it to allPoliciesAllow().
+        (WebCore::ContentSecurityPolicy::allowJavaScriptURLs): Modified to use ContentSecurityPolicy::allPoliciesAllow().
+        (WebCore::ContentSecurityPolicy::allowInlineEventHandlers): Ditto.
+        (WebCore::ContentSecurityPolicy::allowScriptWithNonce): Ditto.
+        (WebCore::ContentSecurityPolicy::allowStyleWithNonce): Ditto.
+        (WebCore::ContentSecurityPolicy::allowInlineScript): Modified to use ContentSecurityPolicy::allPoliciesAllow() and
+        ContentSecurityPolicy::allPoliciesAllowHashFromContent().
+        (WebCore::ContentSecurityPolicy::allowInlineStyle): Ditto.
+        (WebCore::ContentSecurityPolicy::allowEval): Modified to use ContentSecurityPolicy::allPoliciesAllow().
+        (WebCore::ContentSecurityPolicy::allowFrameAncestors): Ditto.
+        (WebCore::ContentSecurityPolicy::allowPluginType): Ditto.
+        (WebCore::ContentSecurityPolicy::allowScriptFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowObjectFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowChildFrameFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowChildContextFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowImageFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowStyleFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowFontFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowMediaFromSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowConnectToSource): Ditto.
+        (WebCore::ContentSecurityPolicy::allowFormAction): Ditto.
+        (WebCore::ContentSecurityPolicy::allowBaseURI): Ditto.
+        (WebCore::isAllowedByAllWithFrame): Deleted.
+        (WebCore::isAllowedByAll): Deleted.
+        (WebCore::isAllowedByAllWithState): Deleted.
+        (WebCore::isAllowedByAllWithContext): Deleted.
+        (WebCore::isAllowedByAllWithNonce): Deleted.
+        (WebCore::isAllowedByAllWithHash): Deleted.
+        (WebCore::isAllowedByAllWithHashFromContent): Deleted.
+        (WebCore::isAllowedByAllWithURL): Deleted.
+        (WebCore::ContentSecurityPolicy::documentEncoding): Deleted. Incorporated its functionality into ContentSecurityPolicy::allPoliciesAllowHashFromContent().
+        (WebCore::ContentSecurityPolicy::isActive): Deleted. This function has been unused since the removal of the CSP script
+        interface in <http://trac.webkit.org/changeset/197142>.
+        * page/csp/ContentSecurityPolicy.h:
+        (WebCore::ContentSecurityPolicy::allPoliciesAllow): Added. Returns whether the predicate function evaluates to true
+        for all CSP policies.
+
 2016-03-23  Jer Noble  <jer.noble@apple.com>
 
         Media elements allowed to play without a user gesture, but requiring fullscreen playback, should not be allowed to autoplay.
index f298998..35ab280 100644 (file)
@@ -174,56 +174,6 @@ bool ContentSecurityPolicy::protocolMatchesSelf(const URL& url) const
     return equalIgnoringASCIICase(url.protocol(), m_selfSourceProtocol);
 }
 
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const Frame&, const URL&, ContentSecurityPolicyDirectiveList::ReportingStatus) const>
-static bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, const Frame& frame, const URL& url, ContentSecurityPolicyDirectiveList::ReportingStatus reportingStatus)
-{
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(frame, url, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(ContentSecurityPolicyDirectiveList::ReportingStatus) const>
-static bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicyDirectiveList::ReportingStatus reportingStatus)
-{
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(JSC::ExecState* state, ContentSecurityPolicyDirectiveList::ReportingStatus) const>
-static bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, JSC::ExecState* state, ContentSecurityPolicyDirectiveList::ReportingStatus reportingStatus)
-{
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(state, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const String&, const WTF::OrdinalNumber&, ContentSecurityPolicyDirectiveList::ReportingStatus) const>
-static bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus reportingStatus)
-{
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(contextURL, contextLine, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const String& nonce) const>
-static bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const String& nonce)
-{
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(nonce))
-            return false;
-    }
-    return true;
-}
-
 static CryptoDigest::Algorithm toCryptoDigestAlgorithm(ContentSecurityPolicyHashAlgorithm algorithm)
 {
     switch (algorithm) {
@@ -238,64 +188,40 @@ static CryptoDigest::Algorithm toCryptoDigestAlgorithm(ContentSecurityPolicyHash
     return CryptoDigest::Algorithm::SHA_512;
 }
 
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const ContentSecurityPolicyHash&) const>
-static bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const ContentSecurityPolicyHash& hash)
+template<typename Predicate>
+bool ContentSecurityPolicy::allPoliciesAllowHashFromContent(Predicate&& predicate, const String& content, OptionSet<ContentSecurityPolicyHashAlgorithm> algorithms) const
 {
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowed)(hash))
-            return false;
-    }
-    return true;
-}
+    // FIXME: We should compute the document encoding once and cache it instead of computing it on each invocation.
+    TextEncoding documentEncoding;
+    if (is<Document>(m_scriptExecutionContext))
+        documentEncoding = downcast<Document>(*m_scriptExecutionContext).textEncoding();
+    const TextEncoding& encodingToUse = documentEncoding.isValid() ? documentEncoding : UTF8Encoding();
 
-template<bool (ContentSecurityPolicyDirectiveList::*allowed)(const ContentSecurityPolicyHash&) const>
-static bool isAllowedByAllWithHashFromContent(const CSPDirectiveListVector& policies, const String& content, const TextEncoding& encoding, OptionSet<ContentSecurityPolicyHashAlgorithm> algorithms)
-{
     // FIXME: Compute the digest with respect to the raw bytes received from the page.
     // See <https://bugs.webkit.org/show_bug.cgi?id=155184>.
-    CString contentCString = encoding.encode(content, EntitiesForUnencodables);
+    CString contentCString = encodingToUse.encode(content, EntitiesForUnencodables);
     for (auto algorithm : algorithms) {
         auto cryptoDigest = CryptoDigest::create(toCryptoDigestAlgorithm(algorithm));
         cryptoDigest->addBytes(contentCString.data(), contentCString.length());
         Vector<uint8_t> digest = cryptoDigest->computeHash();
-        if (isAllowedByAllWithHash<allowed>(policies, { algorithm, digest }))
+        if (allPoliciesAllow(std::forward<Predicate>(predicate), std::make_pair(algorithm, digest)))
             return true;
     }
     return false;
 }
 
-template<bool (ContentSecurityPolicyDirectiveList::*allowFromURL)(const URL&, ContentSecurityPolicyDirectiveList::ReportingStatus) const>
-static bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const URL& url, ContentSecurityPolicyDirectiveList::ReportingStatus reportingStatus)
-{
-    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
-        return true;
-
-    for (auto& policy : policies) {
-        if (!(policy.get()->*allowFromURL)(url, reportingStatus))
-            return false;
-    }
-    return true;
-}
-
 bool ContentSecurityPolicy::allowJavaScriptURLs(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowJavaScriptURLs>(m_policies, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowJavaScriptURLs, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowInlineEventHandlers(const String& contextURL, const WTF::OrdinalNumber& contextLine, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineEventHandlers>(m_policies, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
-}
-
-// FIXME: We should compute the document encoding once and cache it instead of computing it on each invocation.
-const TextEncoding& ContentSecurityPolicy::documentEncoding() const
-{
-    if (!is<Document>(m_scriptExecutionContext))
-        return UTF8Encoding();
-    Document& document = downcast<Document>(*m_scriptExecutionContext);
-    if (TextResourceDecoder* decoder = document.decoder())
-        return decoder->encoding();
-    return UTF8Encoding();
+    if (overrideContentSecurityPolicy)
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowInlineEventHandlers, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce, bool overrideContentSecurityPolicy) const
@@ -305,7 +231,7 @@ bool ContentSecurityPolicy::allowScriptWithNonce(const String& nonce, bool overr
     String strippedNonce = stripLeadingAndTrailingHTMLSpaces(nonce);
     if (strippedNonce.isEmpty())
         return false;
-    if (isAllowedByAllWithNonce<&ContentSecurityPolicyDirectiveList::allowScriptWithNonce>(m_policies, strippedNonce))
+    if (allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowScriptWithNonce, strippedNonce))
         return true;
     return false;
 }
@@ -317,7 +243,7 @@ bool ContentSecurityPolicy::allowStyleWithNonce(const String& nonce, bool overri
     String strippedNonce = stripLeadingAndTrailingHTMLSpaces(nonce);
     if (strippedNonce.isEmpty())
         return false;
-    if (isAllowedByAllWithNonce<&ContentSecurityPolicyDirectiveList::allowStyleWithNonce>(m_policies, strippedNonce))
+    if (allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowStyleWithNonce, strippedNonce))
         return true;
     return false;
 }
@@ -327,9 +253,9 @@ bool ContentSecurityPolicy::allowInlineScript(const String& contextURL, const WT
     if (overrideContentSecurityPolicy)
         return true;
     if (!m_hashAlgorithmsForInlineScripts.isEmpty() && !scriptContent.isEmpty()
-        && isAllowedByAllWithHashFromContent<&ContentSecurityPolicyDirectiveList::allowInlineScriptWithHash>(m_policies, scriptContent, documentEncoding(), m_hashAlgorithmsForInlineScripts))
+        && allPoliciesAllowHashFromContent(&ContentSecurityPolicyDirectiveList::allowInlineScriptWithHash, scriptContent, m_hashAlgorithmsForInlineScripts))
         return true;
-    return isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineScript>(m_policies, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowInlineScript, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, const String& styleContent, bool overrideContentSecurityPolicy) const
@@ -339,14 +265,16 @@ bool ContentSecurityPolicy::allowInlineStyle(const String& contextURL, const WTF
     if (m_overrideInlineStyleAllowed)
         return true;
     if (!m_hashAlgorithmsForInlineStylesheets.isEmpty() && !styleContent.isEmpty()
-        && isAllowedByAllWithHashFromContent<&ContentSecurityPolicyDirectiveList::allowInlineStyleWithHash>(m_policies, styleContent, documentEncoding(), m_hashAlgorithmsForInlineStylesheets))
+        && allPoliciesAllowHashFromContent(&ContentSecurityPolicyDirectiveList::allowInlineStyleWithHash, styleContent, m_hashAlgorithmsForInlineStylesheets))
         return true;
-    return isAllowedByAllWithContext<&ContentSecurityPolicyDirectiveList::allowInlineStyle>(m_policies, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowInlineStyle, contextURL, contextLine, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowEval(JSC::ExecState* state, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithState<&ContentSecurityPolicyDirectiveList::allowEval>(m_policies, state, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowEval, state, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowFrameAncestors(const Frame& frame, const URL& url, bool overrideContentSecurityPolicy) const
@@ -356,78 +284,113 @@ bool ContentSecurityPolicy::allowFrameAncestors(const Frame& frame, const URL& u
     Frame& topFrame = frame.tree().top();
     if (&frame == &topFrame)
         return true;
-    return isAllowedByAllWithFrame<&ContentSecurityPolicyDirectiveList::allowFrameAncestors>(m_policies, frame, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowFrameAncestors, frame, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowPluginType(const String& type, const String& typeAttribute, const URL& url, bool overrideContentSecurityPolicy) const
 {
     if (overrideContentSecurityPolicy)
         return true;
-    for (auto& policy : m_policies) {
-        if (!policy->allowPluginType(type, typeAttribute, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport))
-            return false;
-    }
-    return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowPluginType, type, typeAttribute, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowScriptFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowScriptFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowScriptFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowObjectFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowObjectFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowObjectFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowChildFrameFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowChildFrameFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowChildFrameFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowChildContextFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowChildContextFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowChildContextFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowImageFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowImageFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowImageFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowStyleFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowStyleFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowStyleFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowFontFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFontFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowFontFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowMediaFromSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowMediaFromSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowMediaFromSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowConnectToSource(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowConnectToSource>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowConnectToSource, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowFormAction(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowFormAction>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowFormAction, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 bool ContentSecurityPolicy::allowBaseURI(const URL& url, bool overrideContentSecurityPolicy) const
 {
-    return overrideContentSecurityPolicy || isAllowedByAllWithURL<&ContentSecurityPolicyDirectiveList::allowBaseURI>(m_policies, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
-}
-
-bool ContentSecurityPolicy::isActive() const
-{
-    return !m_policies.isEmpty();
+    if (overrideContentSecurityPolicy)
+        return true;
+    if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol()))
+        return true;
+    return allPoliciesAllow(&ContentSecurityPolicyDirectiveList::allowBaseURI, url, ContentSecurityPolicyDirectiveList::ReportingStatus::SendReport);
 }
 
 ContentSecurityPolicy::ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const
index 26179c2..f32c30d 100644 (file)
@@ -107,8 +107,6 @@ public:
 
     void setOverrideAllowInlineStyle(bool);
 
-    bool isActive() const;
-
     void gatherReportURIs(DOMStringList&) const;
 
     bool experimentalFeaturesEnabled() const;
@@ -157,7 +155,8 @@ private:
 
     void didReceiveHeader(const String&, ContentSecurityPolicyHeaderType, ContentSecurityPolicy::PolicyFrom);
 
-    const TextEncoding& documentEncoding() const;
+    template<typename Predicate, typename... Args> bool allPoliciesAllow(Predicate&&, Args&&...) const WARN_UNUSED_RETURN;
+    template<typename Predicate> bool allPoliciesAllowHashFromContent(Predicate&&, const String& content, OptionSet<ContentSecurityPolicyHashAlgorithm>) const WARN_UNUSED_RETURN;
 
     // We can never have both a script execution context and a frame.
     ScriptExecutionContext* m_scriptExecutionContext { nullptr };
@@ -173,6 +172,16 @@ private:
     OptionSet<ContentSecurityPolicyHashAlgorithm> m_hashAlgorithmsForInlineStylesheets;
 };
 
+template<typename Predicate, typename... Args>
+inline bool ContentSecurityPolicy::allPoliciesAllow(Predicate&& predicate, Args&&... args) const
+{
+    for (auto& policy : m_policies) {
+        if (!(policy.get()->*predicate)(std::forward<Args>(args)...))
+            return false;
+    }
+    return true;
+}
+
 }
 
 #endif