| Index: third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
|
| diff --git a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
|
| index 6449cf9579a44c5258469eff9f25375582c74873..9b00a3a9e96eeb22594921ad171da3d3a909d363 100644
|
| --- a/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
|
| +++ b/third_party/WebKit/Source/core/frame/csp/SourceListDirective.cpp
|
| @@ -617,6 +617,8 @@ bool SourceListDirective::subsumes(
|
| bool allowDynamicOther = other[0]->m_allowDynamic;
|
| bool allowHashedAttributesOther = other[0]->m_allowHashedAttributes;
|
| bool isHashOrNoncePresentOther = other[0]->isHashOrNoncePresent();
|
| + HashSet<String> noncesB = other[0]->m_nonces;
|
| + HashSet<CSPHashValue> hashesB = other[0]->m_hashes;
|
|
|
| for (size_t i = 1; i < other.size(); i++) {
|
| allowInlineOther = allowInlineOther && other[i]->m_allowInline;
|
| @@ -626,9 +628,14 @@ bool SourceListDirective::subsumes(
|
| allowHashedAttributesOther && other[i]->m_allowHashedAttributes;
|
| isHashOrNoncePresentOther =
|
| isHashOrNoncePresentOther && other[i]->isHashOrNoncePresent();
|
| + noncesB = other[i]->getIntersectNonces(noncesB);
|
| + hashesB = other[i]->getIntersectHashes(hashesB);
|
| normalizedB = other[i]->getIntersectCSPSources(normalizedB);
|
| }
|
|
|
| + if (!subsumesNoncesAndHashes(noncesB, hashesB))
|
| + return false;
|
| +
|
| const ContentSecurityPolicy::DirectiveType type =
|
| ContentSecurityPolicy::getDirectiveType(m_directiveName);
|
| if (type == ContentSecurityPolicy::DirectiveType::ScriptSrc ||
|
| @@ -648,6 +655,49 @@ bool SourceListDirective::subsumes(
|
| return CSPSource::firstSubsumesSecond(normalizedA, normalizedB);
|
| }
|
|
|
| +bool SourceListDirective::subsumesNoncesAndHashes(
|
| + const HashSet<String>& nonces,
|
| + const HashSet<CSPHashValue> hashes) {
|
| + for (const auto& nonce : nonces) {
|
| + if (!m_nonces.contains(nonce))
|
| + return false;
|
| + }
|
| + for (const auto& hash : hashes) {
|
| + if (!m_hashes.contains(hash))
|
| + return false;
|
| + }
|
| +
|
| + return true;
|
| +}
|
| +
|
| +HashSet<String> SourceListDirective::getIntersectNonces(
|
| + const HashSet<String>& other) {
|
| + if (!m_nonces.size() || !other.size())
|
| + return !m_nonces.size() ? m_nonces : other;
|
| +
|
| + HashSet<String> normalized;
|
| + for (const auto& nonce : m_nonces) {
|
| + if (other.contains(nonce))
|
| + normalized.add(nonce);
|
| + }
|
| +
|
| + return normalized;
|
| +}
|
| +
|
| +HashSet<CSPHashValue> SourceListDirective::getIntersectHashes(
|
| + const HashSet<CSPHashValue>& other) {
|
| + if (!m_hashes.size() || !other.size())
|
| + return !m_hashes.size() ? m_hashes : other;
|
| +
|
| + HashSet<CSPHashValue> normalized;
|
| + for (const auto& hash : m_hashes) {
|
| + if (other.contains(hash))
|
| + normalized.add(hash);
|
| + }
|
| +
|
| + return normalized;
|
| +}
|
| +
|
| HashMap<String, CSPSource*> SourceListDirective::getIntersectSchemesOnly(
|
| HeapVector<Member<CSPSource>> other) {
|
| HashMap<String, CSPSource*> schemesA;
|
|
|