// source = scheme ":" // / ( [ scheme "://" ] host [ port ] ) // / "'self'" // bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, bool& hostHasWildcard, bool& portHasWildcard) { if (begin == end) return false; if (equalIgnoringCase("'self'", begin, end - begin)) { addSourceSelf(); return false; } if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) { addSourceUnsafeInline(); return false; } if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) { addSourceUnsafeEval(); return false; } const UChar* position = begin; const UChar* beginHost = begin; skipUtil(position, end, ':'); if (position == end) { // This must be a host-only source. if (!parseHost(beginHost, position, host, hostHasWildcard)) return false; return true; } if (end - position == 1) { ASSERT(*position == ':'); // This must be a scheme-only source. if (!parseScheme(begin, position, scheme)) return false; return true; } ASSERT(end - position >= 2); if (position[1] == '/') { if (!parseScheme(begin, position, scheme) || !skipExactly(position, end, ':') || !skipExactly(position, end, '/') || !skipExactly(position, end, '/')) return false; beginHost = position; skipUtil(position, end, ':'); } if (position == beginHost) return false; if (!parseHost(beginHost, position, host, hostHasWildcard)) return false; if (position == end) { port = 0; return true; } if (!skipExactly(position, end, ':')) ASSERT_NOT_REACHED(); if (!parsePort(position, end, port, portHasWildcard)) return false; return true; }
// source = scheme ":" // / ( [ scheme "://" ] host [ port ] [ path ] ) // / "'self'" bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, CSPSource::WildcardDisposition& hostWildcard, CSPSource::WildcardDisposition& portWildcard) { if (begin == end) return false; if (equalIgnoringCase("'none'", begin, end - begin)) return false; if (end - begin == 1 && *begin == '*') { addSourceStar(); return true; } if (equalIgnoringCase("'self'", begin, end - begin)) { addSourceSelf(); return true; } if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) { addSourceUnsafeInline(); return true; } if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) { addSourceUnsafeEval(); return true; } String nonce; if (!parseNonce(begin, end, nonce)) return false; if (!nonce.isNull()) { addSourceNonce(nonce); return true; } DigestValue hash; ContentSecurityPolicyHashAlgorithm algorithm = ContentSecurityPolicyHashAlgorithmNone; if (!parseHash(begin, end, hash, algorithm)) return false; if (hash.size() > 0) { addSourceHash(algorithm, hash); return true; } const UChar* position = begin; const UChar* beginHost = begin; const UChar* beginPath = end; const UChar* beginPort = 0; skipWhile<UChar, isNotColonOrSlash>(position, end); if (position == end) { // host // ^ return parseHost(beginHost, position, host, hostWildcard); } if (position < end && *position == '/') { // host/path || host/ || / // ^ ^ ^ return parseHost(beginHost, position, host, hostWildcard) && parsePath(position, end, path); } if (position < end && *position == ':') { if (end - position == 1) { // scheme: // ^ return parseScheme(begin, position, scheme); } if (position[1] == '/') { // scheme://host || scheme:// // ^ ^ if (!parseScheme(begin, position, scheme) || !skipExactly<UChar>(position, end, ':') || !skipExactly<UChar>(position, end, '/') || !skipExactly<UChar>(position, end, '/')) return false; if (position == end) return false; beginHost = position; skipWhile<UChar, isNotColonOrSlash>(position, end); } if (position < end && *position == ':') { // host:port || scheme://host:port // ^ ^ beginPort = position; skipUntil<UChar>(position, end, '/'); } } if (position < end && *position == '/') { // scheme://host/path || scheme://host:port/path // ^ ^ if (position == beginHost) return false; beginPath = position; } if (!parseHost(beginHost, beginPort ? beginPort : beginPath, host, hostWildcard)) return false; if (beginPort) { if (!parsePort(beginPort, beginPath, port, portWildcard)) return false; } else { port = 0; } if (beginPath != end) { if (!parsePath(beginPath, end, path)) return false; } return true; }