1d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
2d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
3d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// found in the LICENSE file.
4d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
5d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "config.h"
6d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/csp/CSPSourceList.h"
7d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
8d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/csp/CSPSource.h"
9d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "core/frame/csp/ContentSecurityPolicy.h"
10d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/ParsingUtilities.h"
11d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/weborigin/KURL.h"
12d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "platform/weborigin/SecurityOrigin.h"
13d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/HashSet.h"
14d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/text/Base64.h"
15d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)#include "wtf/text/WTFString.h"
16d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
17c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)namespace blink {
18d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
19d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)static bool isSourceListNone(const UChar* begin, const UChar* end)
20d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
21d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(begin, end);
22d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
23d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
24d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isSourceCharacter>(position, end);
25d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!equalIgnoringCase("'none'", begin, position - begin))
26d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
27d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
28d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIISpace>(position, end);
29d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position != end)
30d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
31d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
32d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
33d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
34d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
35d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)CSPSourceList::CSPSourceList(ContentSecurityPolicy* policy, const String& directiveName)
36d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    : m_policy(policy)
37d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_directiveName(directiveName)
387242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    , m_allowSelf(false)
39d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_allowStar(false)
40d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_allowInline(false)
41d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_allowEval(false)
42d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    , m_hashAlgorithmsUsed(0)
43d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
44d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
45d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
46d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::matches(const KURL& url) const
47d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
48d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (m_allowStar)
49d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
50d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
51d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    KURL effectiveURL = SecurityOrigin::shouldUseInnerURL(url) ? SecurityOrigin::extractInnerURL(url) : url;
52d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
537242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (m_allowSelf && m_policy->urlMatchesSelf(effectiveURL))
547242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return true;
557242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci
56d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for (size_t i = 0; i < m_list.size(); ++i) {
57d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (m_list[i].matches(effectiveURL))
58d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return true;
59d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
60d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
61d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return false;
62d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
63d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
64d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::allowInline() const
65d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
66d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_allowInline;
67d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
68d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
69d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::allowEval() const
70d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
71d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_allowEval;
72d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
73d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
74d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::allowNonce(const String& nonce) const
75d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
76d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !nonce.isNull() && m_nonces.contains(nonce);
77d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
78d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
79d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::allowHash(const CSPHashValue& hashValue) const
80d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
81d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_hashes.contains(hashValue);
82d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
83d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
84d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)uint8_t CSPSourceList::hashAlgorithmsUsed() const
85d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
86d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return m_hashAlgorithmsUsed;
87d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
88d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
89d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::isHashOrNoncePresent() const
90d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
91d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return !m_nonces.isEmpty() || m_hashAlgorithmsUsed != ContentSecurityPolicyHashAlgorithmNone;
92d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
93d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
94d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// source-list       = *WSP [ source *( 1*WSP source ) *WSP ]
95d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//                   / *WSP "'none'" *WSP
96d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
97d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::parse(const UChar* begin, const UChar* end)
98d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
99d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // We represent 'none' as an empty m_list.
100d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (isSourceListNone(begin, end))
101d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return;
102d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
103d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
104d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (position < end) {
105d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isASCIISpace>(position, end);
106d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position == end)
107d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return;
108d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
109d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const UChar* beginSource = position;
110d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isSourceCharacter>(position, end);
111d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
112d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        String scheme, host, path;
113d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        int port = 0;
1147242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CSPSource::WildcardDisposition hostWildcard = CSPSource::NoWildcard;
1157242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        CSPSource::WildcardDisposition portWildcard = CSPSource::NoWildcard;
116d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
1177242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (parseSource(beginSource, position, scheme, host, port, path, hostWildcard, portWildcard)) {
118d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // Wildcard hosts and keyword sources ('self', 'unsafe-inline',
119d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // etc.) aren't stored in m_list, but as attributes on the source
120d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // list itself.
121d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (scheme.isEmpty() && host.isEmpty())
122d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                continue;
123d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (m_policy->isDirectiveName(host))
124d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                m_policy->reportDirectiveAsSourceExpression(m_directiveName, host);
1257242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci            m_list.append(CSPSource(m_policy, scheme, host, port, path, hostWildcard, portWildcard));
126d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        } else {
127d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            m_policy->reportInvalidSourceExpression(m_directiveName, String(beginSource, position - beginSource));
128d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
129d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
130d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ASSERT(position == end || isASCIISpace(*position));
131d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
132d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
133d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
134d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// source            = scheme ":"
135d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//                   / ( [ scheme "://" ] host [ port ] [ path ] )
136d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//                   / "'self'"
1377242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, CSPSource::WildcardDisposition& hostWildcard, CSPSource::WildcardDisposition& portWildcard)
138d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
139d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (begin == end)
140d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
141d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
142d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("'none'", begin, end - begin))
143d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
144d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
145d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (end - begin == 1 && *begin == '*') {
146d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        addSourceStar();
147d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
148d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
149d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
150d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("'self'", begin, end - begin)) {
151d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        addSourceSelf();
152d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
153d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
154d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
155d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) {
156d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        addSourceUnsafeInline();
157d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
158d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
159d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
160d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) {
161d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        addSourceUnsafeEval();
162d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
163d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
164d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
165aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    String nonce;
166aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (!parseNonce(begin, end, nonce))
167aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return false;
168d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
169aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (!nonce.isNull()) {
170aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        addSourceNonce(nonce);
171aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return true;
172aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    }
173d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
174aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    DigestValue hash;
175aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    ContentSecurityPolicyHashAlgorithm algorithm = ContentSecurityPolicyHashAlgorithmNone;
176aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (!parseHash(begin, end, hash, algorithm))
177aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return false;
178d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
179aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch    if (hash.size() > 0) {
180aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        addSourceHash(algorithm, hash);
181aafa69cb17c9d6606c07663ade5f81388a2c5986Ben Murdoch        return true;
182d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
183d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
184d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
185d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* beginHost = begin;
186d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* beginPath = end;
187d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* beginPort = 0;
188d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
189d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isNotColonOrSlash>(position, end);
190d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
191d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position == end) {
192d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // host
193d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        //     ^
1947242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return parseHost(beginHost, position, host, hostWildcard);
195d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
196d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
197d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position < end && *position == '/') {
198d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // host/path || host/ || /
199d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        //     ^            ^    ^
2007242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        return parseHost(beginHost, position, host, hostWildcard) && parsePath(position, end, path);
201d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
202d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
203d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position < end && *position == ':') {
204d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (end - position == 1) {
205d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // scheme:
206d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //       ^
207d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return parseScheme(begin, position, scheme);
208d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
209d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
210d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position[1] == '/') {
211d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // scheme://host || scheme://
212d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //       ^                ^
213d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (!parseScheme(begin, position, scheme)
214d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                || !skipExactly<UChar>(position, end, ':')
215d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                || !skipExactly<UChar>(position, end, '/')
216d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                || !skipExactly<UChar>(position, end, '/'))
217d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)                return false;
218d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            if (position == end)
2199e12abdf8c3a23d52091ea54ebb6a04d327f9300Torne (Richard Coles)                return false;
220d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            beginHost = position;
221d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            skipWhile<UChar, isNotColonOrSlash>(position, end);
222d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
223d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
224d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position < end && *position == ':') {
225d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            // host:port || scheme://host:port
226d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            //     ^                     ^
227d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            beginPort = position;
228d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            skipUntil<UChar>(position, end, '/');
229d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
230d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
231d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
232d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position < end && *position == '/') {
233d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        // scheme://host/path || scheme://host:port/path
234d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        //              ^                          ^
235d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position == beginHost)
236d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
237d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        beginPath = position;
238d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
239d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
2407242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostWildcard))
241d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
242d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
243d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (beginPort) {
2447242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        if (!parsePort(beginPort, beginPath, port, portWildcard))
245d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
246d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } else {
247d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        port = 0;
248d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
249d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
250d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (beginPath != end) {
251d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!parsePath(beginPath, end, path))
252d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
253d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
254d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
255d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
256d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
257d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
258d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// nonce-source      = "'nonce-" nonce-value "'"
259d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// nonce-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
260d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
261d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::parseNonce(const UChar* begin, const UChar* end, String& nonce)
262d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
263d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    DEFINE_STATIC_LOCAL(const String, noncePrefix, ("'nonce-"));
264d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
265d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!equalIgnoringCase(noncePrefix.characters8(), begin, noncePrefix.length()))
266d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
267d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
268d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin + noncePrefix.length();
269d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* nonceBegin = position;
270d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
271d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isNonceCharacter>(position, end);
272d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(nonceBegin <= position);
273d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
274d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if ((position + 1) != end || *position != '\'' || !(position - nonceBegin))
275d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
276d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
277d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    nonce = String(nonceBegin, position - nonceBegin);
278d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
279d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
280d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
281d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// hash-source       = "'" hash-algorithm "-" hash-value "'"
282d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// hash-algorithm    = "sha1" / "sha256" / "sha384" / "sha512"
283d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// hash-value        = 1*( ALPHA / DIGIT / "+" / "/" / "=" )
284d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
285d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::parseHash(const UChar* begin, const UChar* end, DigestValue& hash, ContentSecurityPolicyHashAlgorithm& hashAlgorithm)
286d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
287d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Any additions or subtractions from this struct should also modify the
288d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // respective entries in the kAlgorithmMap array in checkDigest().
289d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    static const struct {
290d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        const char* prefix;
291d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ContentSecurityPolicyHashAlgorithm algorithm;
292d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    } kSupportedPrefixes[] = {
293d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        { "'sha1-", ContentSecurityPolicyHashAlgorithmSha1 },
294d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        { "'sha256-", ContentSecurityPolicyHashAlgorithmSha256 },
295d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        { "'sha384-", ContentSecurityPolicyHashAlgorithmSha384 },
296d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        { "'sha512-", ContentSecurityPolicyHashAlgorithmSha512 }
297d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    };
298d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
299d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    String prefix;
300d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    hashAlgorithm = ContentSecurityPolicyHashAlgorithmNone;
301d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
302d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Instead of this sizeof() calculation to get the length of this array,
303d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // it would be preferable to use WTF_ARRAY_LENGTH for simplicity and to
304d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // guarantee a compile time calculation. Unfortunately, on some
305d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // compliers, the call to WTF_ARRAY_LENGTH fails on arrays of anonymous
306d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // stucts, so, for now, it is necessary to resort to this sizeof
307d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // calculation.
308d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    for (size_t i = 0; i < (sizeof(kSupportedPrefixes) / sizeof(kSupportedPrefixes[0])); i++) {
309d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (equalIgnoringCase(kSupportedPrefixes[i].prefix, begin, strlen(kSupportedPrefixes[i].prefix))) {
310d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            prefix = kSupportedPrefixes[i].prefix;
311d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            hashAlgorithm = kSupportedPrefixes[i].algorithm;
312d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            break;
313d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        }
314d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
315d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
316d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (hashAlgorithm == ContentSecurityPolicyHashAlgorithmNone)
317d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
318d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
319d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin + prefix.length();
320d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* hashBegin = position;
321d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
322d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isBase64EncodedCharacter>(position, end);
323d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(hashBegin <= position);
324d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
325d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // Base64 encodings may end with exactly one or two '=' characters
326d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipExactly<UChar>(position, position + 1, '=');
327d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipExactly<UChar>(position, position + 1, '=');
328d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
329d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if ((position + 1) != end || *position != '\'' || !(position - hashBegin))
330d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
331d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
332d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    Vector<char> hashVector;
333d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    base64Decode(hashBegin, position - hashBegin, hashVector);
334d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (hashVector.size() > kMaxDigestSize)
335d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
336d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    hash.append(reinterpret_cast<uint8_t*>(hashVector.data()), hashVector.size());
337d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
338d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
339d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
340d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//                     ; <scheme> production from RFC 3986
341d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
342d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
343d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::parseScheme(const UChar* begin, const UChar* end, String& scheme)
344d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
345d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(begin <= end);
346d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(scheme.isEmpty());
347d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
348d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (begin == end)
349d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
350d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
351d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
352d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
353d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!skipExactly<UChar, isASCIIAlpha>(position, end))
354d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
355d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
356d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isSchemeContinuationCharacter>(position, end);
357d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
358d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position != end)
359d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
360d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
361d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    scheme = String(begin, end - begin);
362d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
363d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
364d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
365d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// host              = [ "*." ] 1*host-char *( "." 1*host-char )
366d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//                   / "*"
367d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// host-char         = ALPHA / DIGIT / "-"
368d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
3697242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool CSPSourceList::parseHost(const UChar* begin, const UChar* end, String& host, CSPSource::WildcardDisposition& hostWildcard)
370d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
371d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(begin <= end);
372d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(host.isEmpty());
3737242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(hostWildcard == CSPSource::NoWildcard);
374d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
375d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (begin == end)
376d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
377d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
378d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
379d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
380d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (skipExactly<UChar>(position, end, '*')) {
3817242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        hostWildcard = CSPSource::HasWildcard;
382d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
383d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position == end)
384d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return true;
385d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
386d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!skipExactly<UChar>(position, end, '.'))
387d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
388d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
389d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
390d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* hostBegin = position;
391d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
392d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    while (position < end) {
393d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (!skipExactly<UChar, isHostCharacter>(position, end))
394d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
395d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
396d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        skipWhile<UChar, isHostCharacter>(position, end);
397d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
398d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        if (position < end && !skipExactly<UChar>(position, end, '.'))
399d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)            return false;
400d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
401d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
402d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(position == end);
403d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    host = String(hostBegin, end - hostBegin);
404d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
405d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
406d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
407d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)bool CSPSourceList::parsePath(const UChar* begin, const UChar* end, String& path)
408d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
409d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(begin <= end);
410d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(path.isEmpty());
411d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
412d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
413d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isPathComponentCharacter>(position, end);
414d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    // path/to/file.js?query=string || path/to/file.js#anchor
415d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    //                ^                               ^
416d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position < end)
417d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        m_policy->reportInvalidPathCharacter(m_directiveName, String(begin, end - begin), *position);
418d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
419d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    path = decodeURLEscapeSequences(String(begin, position - begin));
420d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
421d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(position <= end);
422d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(position == end || (*position == '#' || *position == '?'));
423d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return true;
424d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
425d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
426d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)// port              = ":" ( 1*DIGIT / "*" )
427d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)//
4287242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tuccibool CSPSourceList::parsePort(const UChar* begin, const UChar* end, int& port, CSPSource::WildcardDisposition& portWildcard)
429d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
430d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(begin <= end);
431d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    ASSERT(!port);
4327242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    ASSERT(portWildcard == CSPSource::NoWildcard);
433d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
434d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (!skipExactly<UChar>(begin, end, ':'))
435d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        ASSERT_NOT_REACHED();
436d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
437d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (begin == end)
438d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
439d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
440d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (end - begin == 1 && *begin == '*') {
441d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        port = 0;
4427242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci        portWildcard = CSPSource::HasWildcard;
443d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return true;
444d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    }
445d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
446d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    const UChar* position = begin;
447d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    skipWhile<UChar, isASCIIDigit>(position, end);
448d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
449d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    if (position != end)
450d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)        return false;
451d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
452d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    bool ok;
453d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    port = charactersToIntStrict(begin, end - begin, &ok);
454d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    return ok;
455d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
456d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
457d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceSelf()
458d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
4597242dc3dbeb210b5e876a3c42d1ec1a667fc621aPrimiano Tucci    m_allowSelf = true;
460d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
461d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
462d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceStar()
463d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
464d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_allowStar = true;
465d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
466d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
467d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceUnsafeInline()
468d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
469d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_allowInline = true;
470d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
471d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
472d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceUnsafeEval()
473d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
474d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_allowEval = true;
475d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
476d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
477d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceNonce(const String& nonce)
478d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
479d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_nonces.add(nonce);
480d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
481d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
482d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)void CSPSourceList::addSourceHash(const ContentSecurityPolicyHashAlgorithm& algorithm, const DigestValue& hash)
483d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles){
484d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_hashes.add(CSPHashValue(algorithm, hash));
485d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)    m_hashAlgorithmsUsed |= algorithm;
486d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)}
487d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
488d5428f32f5d1719f774f62e19147104ca245a3abTorne (Richard Coles)
489c1847b1379d12d0e05df27436bf19a9b1bf12deaTorne (Richard Coles)} // namespace blink
490