String CSPDirectiveList::parseSuboriginName(const String& policy)
{
    Vector<UChar> characters;
    policy.appendTo(characters);

    const UChar* position = characters.data();
    const UChar* end = position + characters.size();

    // Parse the name of the suborigin (no spaces, single string)
    skipWhile<UChar, isASCIISpace>(position, end);
    if (position == end) {
        m_policy->reportInvalidSuboriginFlags("No suborigin name specified.");
        return String();
    }

    const UChar* begin = position;

    skipWhile<UChar, isASCIIAlphanumeric>(position, end);
    if (position != end && !isASCIISpace(*position)) {
        m_policy->reportInvalidSuboriginFlags("Invalid character \'" + String(position, 1) + "\' in suborigin.");
        return String();
    }
    size_t length = position - begin;
    skipWhile<UChar, isASCIISpace>(position, end);
    if (position != end) {
        m_policy->reportInvalidSuboriginFlags("Whitespace is not allowed in suborigin names.");
        return String();
    }

    return String(begin, length);
}
Пример #2
0
MediaListDirective::MediaListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
    : CSPDirective(name, value, policy)
{
    Vector<UChar> characters;
    value.appendTo(characters);
    parse(characters.data(), characters.data() + characters.size());
}
Пример #3
0
void CSPDirectiveList::parseReportURI(const String& name, const String& value)
{
    if (!m_reportEndpoints.isEmpty()) {
        m_policy->reportDuplicateDirective(name);
        return;
    }

    Vector<UChar> characters;
    value.appendTo(characters);

    const UChar* position = characters.data();
    const UChar* end = position + characters.size();

    while (position < end) {
        skipWhile<UChar, isASCIISpace>(position, end);

        const UChar* urlBegin = position;
        skipWhile<UChar, isNotASCIISpace>(position, end);

        if (urlBegin < position) {
            String url = String(urlBegin, position - urlBegin);
            m_reportEndpoints.append(url);
        }
    }
}
void checkTextOfParagraph(TextCheckerClient& client, const String& text, TextCheckingTypeMask checkingTypes, Vector<TextCheckingResult>& results)
{
    Vector<UChar> characters;
    text.appendTo(characters);
    unsigned length = text.length();

    Vector<TextCheckingResult> spellingResult;
    if (checkingTypes & TextCheckingTypeSpelling)
        findMisspellings(client, characters.data(), 0, length, spellingResult);

    Vector<TextCheckingResult> grammarResult;
    if (checkingTypes & TextCheckingTypeGrammar) {
        // Only checks grammartical error before the first misspellings
        int grammarCheckLength = length;
        for (const auto& spelling : spellingResult) {
            if (spelling.location < grammarCheckLength)
                grammarCheckLength = spelling.location;
        }

        findBadGrammars(client, characters.data(), 0, grammarCheckLength, grammarResult);
    }

    if (grammarResult.size())
        results.swap(grammarResult);

    if (spellingResult.size()) {
        if (results.isEmpty())
            results.swap(spellingResult);
        else
            results.appendVector(spellingResult);
    }
}
SourceListDirective::SourceListDirective(const String& name, const String& value, ContentSecurityPolicy* policy)
    : CSPDirective(name, value, policy)
    , m_sourceList(policy, name)
{
    Vector<UChar> characters;
    value.appendTo(characters);

    m_sourceList.parse(characters.data(), characters.data() + characters.size());
}
Пример #6
0
void CSPDirectiveList::parseReferrer(const String& name, const String& value)
{
    if (m_didSetReferrerPolicy) {
        m_policy->reportDuplicateDirective(name);
        m_referrerPolicy = ReferrerPolicyNever;
        return;
    }

    m_didSetReferrerPolicy = true;

    if (value.isEmpty()) {
        m_policy->reportInvalidReferrer(value);
        m_referrerPolicy = ReferrerPolicyNever;
        return;
    }

    Vector<UChar> characters;
    value.appendTo(characters);

    const UChar* position = characters.data();
    const UChar* end = position + characters.size();

    skipWhile<UChar, isASCIISpace>(position, end);
    const UChar* begin = position;
    skipWhile<UChar, isNotASCIISpace>(position, end);

    // value1
    //       ^
    if (equalIgnoringCase("unsafe-url", begin, position - begin)) {
        m_referrerPolicy = ReferrerPolicyAlways;
    } else if (equalIgnoringCase("no-referrer", begin, position - begin)) {
        m_referrerPolicy = ReferrerPolicyNever;
    } else if (equalIgnoringCase("no-referrer-when-downgrade", begin, position - begin)) {
        m_referrerPolicy = ReferrerPolicyDefault;
    } else if (equalIgnoringCase("origin", begin, position - begin)) {
        m_referrerPolicy = ReferrerPolicyOrigin;
    } else if (equalIgnoringCase("origin-when-crossorigin", begin, position - begin)) {
        m_referrerPolicy = ReferrerPolicyOriginWhenCrossOrigin;
    } else {
        m_referrerPolicy = ReferrerPolicyNever;
        m_policy->reportInvalidReferrer(value);
        return;
    }

    skipWhile<UChar, isASCIISpace>(position, end);
    if (position == end)
        return;

    // value1 value2
    //        ^
    m_referrerPolicy = ReferrerPolicyNever;
    m_policy->reportInvalidReferrer(value);

}
Пример #7
0
    void expectMimeType(const String& text, const char* expectedType)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* end = characters.end();
        String type;

        EXPECT_TRUE(SubresourceIntegrity::parseMimeType(position, end, type));
        EXPECT_EQ(expectedType, type);
    }
Пример #8
0
    void expectDigest(const String& text, const char* expectedDigest)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* end = characters.end();
        String digest;

        EXPECT_TRUE(SubresourceIntegrity::parseDigest(position, end, digest));
        EXPECT_EQ(expectedDigest, digest);
    }
Пример #9
0
    void expectDigestFailure(const String& text)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* end = characters.end();
        String digest;

        EXPECT_FALSE(SubresourceIntegrity::parseDigest(position, end, digest));
        EXPECT_TRUE(digest.isEmpty());
    }
Пример #10
0
    void expectMimeTypeFailure(const String& text)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* end = characters.end();
        String type;

        EXPECT_FALSE(SubresourceIntegrity::parseMimeType(position, end, type));
        EXPECT_TRUE(type.isEmpty());
    }
Пример #11
0
    void expectAlgorithmFailure(const String& text)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* begin = characters.data();
        const UChar* end = characters.end();
        HashAlgorithm algorithm;

        EXPECT_FALSE(SubresourceIntegrity::parseAlgorithm(position, end, algorithm));
        EXPECT_EQ(begin, position);
    }
Пример #12
0
    void expectAlgorithm(const String& text, HashAlgorithm expectedAlgorithm)
    {
        Vector<UChar> characters;
        text.appendTo(characters);
        const UChar* position = characters.data();
        const UChar* end = characters.end();
        HashAlgorithm algorithm;

        EXPECT_TRUE(SubresourceIntegrity::parseAlgorithm(position, end, algorithm));
        EXPECT_EQ(expectedAlgorithm, algorithm);
        EXPECT_EQ(';', *position);
    }
// Tests that report-uri directives are discarded from policies
// delivered in <meta> elements.
TEST_F(ContentSecurityPolicyTest, ReportURIInMeta)
{
    String policy = "img-src 'none'; report-uri http://foo.test";
    Vector<UChar> characters;
    policy.appendTo(characters);
    const UChar* begin = characters.data();
    const UChar* end = begin + characters.size();
    CSPDirectiveList* directiveList(CSPDirectiveList::create(csp, begin, end, ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceMeta));
    EXPECT_TRUE(directiveList->reportEndpoints().isEmpty());
    directiveList = CSPDirectiveList::create(csp, begin, end, ContentSecurityPolicyHeaderTypeEnforce, ContentSecurityPolicyHeaderSourceHTTP);
    EXPECT_FALSE(directiveList->reportEndpoints().isEmpty());
}
Пример #14
0
inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
    : m_options(options)
    , m_prefixLength(0)
    , m_numberOfCharactersJustAppended(0)
    , m_atBreak(true)
    , m_needsMoreContext(options & AtWordStarts)
    , m_targetRequiresKanaWorkaround(containsKanaLetters(target))
{
    ASSERT(!target.isEmpty());
    target.appendTo(m_target);

    // FIXME: We'd like to tailor the searcher to fold quote marks for us instead
    // of doing it in a separate replacement pass here, but ICU doesn't offer a way
    // to add tailoring on top of the locale-specific tailoring as of this writing.
    foldQuoteMarksAndSoftHyphens(m_target.data(), m_target.size());

    size_t targetLength = m_target.size();
    m_buffer.reserveInitialCapacity(std::max(targetLength * 8, minimumSearchBufferSize));
    m_overlap = m_buffer.capacity() / 4;

    if ((m_options & AtWordStarts) && targetLength) {
        UChar32 targetFirstCharacter;
        U16_GET(m_target.data(), 0, 0, targetLength, targetFirstCharacter);
        // Characters in the separator category never really occur at the beginning of a word,
        // so if the target begins with such a character, we just ignore the AtWordStart option.
        if (isSeparator(targetFirstCharacter)) {
            m_options &= ~AtWordStarts;
            m_needsMoreContext = false;
        }
    }

    // Grab the single global searcher.
    // If we ever have a reason to do more than once search buffer at once, we'll have
    // to move to multiple searchers.
    lockSearcher();

    UStringSearch* searcher = blink::searcher();
    UCollator* collator = usearch_getCollator(searcher);

    UCollationStrength strength = m_options & CaseInsensitive ? UCOL_PRIMARY : UCOL_TERTIARY;
    if (ucol_getStrength(collator) != strength) {
        ucol_setStrength(collator, strength);
        usearch_reset(searcher);
    }

    UErrorCode status = U_ZERO_ERROR;
    usearch_setPattern(searcher, m_target.data(), targetLength, &status);
    ASSERT(status == U_ZERO_ERROR);

    // The kana workaround requires a normalized copy of the target string.
    if (m_targetRequiresKanaWorkaround)
        normalizeCharactersIntoNFCForm(m_target.data(), m_target.size(), m_normalizedTarget);
}
Пример #15
0
void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value)
{
    if (m_reflectedXSSDisposition != ReflectedXSSUnset) {
        m_policy->reportDuplicateDirective(name);
        m_reflectedXSSDisposition = ReflectedXSSInvalid;
        return;
    }

    if (value.isEmpty()) {
        m_reflectedXSSDisposition = ReflectedXSSInvalid;
        m_policy->reportInvalidReflectedXSS(value);
        return;
    }

    Vector<UChar> characters;
    value.appendTo(characters);

    const UChar* position = characters.data();
    const UChar* end = position + characters.size();

    skipWhile<UChar, isASCIISpace>(position, end);
    const UChar* begin = position;
    skipWhile<UChar, isNotASCIISpace>(position, end);

    // value1
    //       ^
    if (equalIgnoringCase("allow", begin, position - begin)) {
        m_reflectedXSSDisposition = AllowReflectedXSS;
    } else if (equalIgnoringCase("filter", begin, position - begin)) {
        m_reflectedXSSDisposition = FilterReflectedXSS;
    } else if (equalIgnoringCase("block", begin, position - begin)) {
        m_reflectedXSSDisposition = BlockReflectedXSS;
    } else {
        m_reflectedXSSDisposition = ReflectedXSSInvalid;
        m_policy->reportInvalidReflectedXSS(value);
        return;
    }

    skipWhile<UChar, isASCIISpace>(position, end);
    if (position == end && m_reflectedXSSDisposition != ReflectedXSSUnset)
        return;

    // value1 value2
    //        ^
    m_reflectedXSSDisposition = ReflectedXSSInvalid;
    m_policy->reportInvalidReflectedXSS(value);
}
Пример #16
0
inline SearchBuffer::SearchBuffer(const String& target, FindOptions options)
    : m_options(options),
      m_prefixLength(0),
      m_numberOfCharactersJustAppended(0),
      m_atBreak(true),
      m_needsMoreContext(options & AtWordStarts),
      m_targetRequiresKanaWorkaround(containsKanaLetters(target)) {
  DCHECK(!target.isEmpty()) << target;
  target.appendTo(m_target);

  // FIXME: We'd like to tailor the searcher to fold quote marks for us instead
  // of doing it in a separate replacement pass here, but ICU doesn't offer a
  // way to add tailoring on top of the locale-specific tailoring as of this
  // writing.
  foldQuoteMarksAndSoftHyphens(m_target.data(), m_target.size());

  size_t targetLength = m_target.size();
  m_buffer.reserveInitialCapacity(
      std::max(targetLength * 8, kMinimumSearchBufferSize));
  m_overlap = m_buffer.capacity() / 4;

  if ((m_options & AtWordStarts) && targetLength) {
    const UChar32 targetFirstCharacter =
        getCodePointAt(m_target.data(), 0, targetLength);
    // Characters in the separator category never really occur at the beginning
    // of a word, so if the target begins with such a character, we just ignore
    // the AtWordStart option.
    if (isSeparator(targetFirstCharacter)) {
      m_options &= ~AtWordStarts;
      m_needsMoreContext = false;
    }
  }

  m_textSearcher = WTF::makeUnique<TextSearcherICU>();
  m_textSearcher->setPattern(StringView(m_target.data(), m_target.size()),
                             !(m_options & CaseInsensitive));

  // The kana workaround requires a normalized copy of the target string.
  if (m_targetRequiresKanaWorkaround)
    normalizeCharactersIntoNFCForm(m_target.data(), m_target.size(),
                                   m_normalizedTarget);
}
Пример #17
0
void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, ContentSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
{
    // If this is a report-only header inside a <meta> element, bail out.
    if (source == ContentSecurityPolicyHeaderSourceMeta && type == ContentSecurityPolicyHeaderTypeReport && experimentalFeaturesEnabled()) {
        reportReportOnlyInMeta(header);
        return;
    }

    Vector<UChar> characters;
    header.appendTo(characters);

    const UChar* begin = characters.data();
    const UChar* end = begin + characters.size();

    // RFC2616, section 4.2 specifies that headers appearing multiple times can
    // be combined with a comma. Walk the header string, and parse each comma
    // separated chunk as a separate header.
    const UChar* position = begin;
    while (position < end) {
        skipUntil<UChar>(position, end, ',');

        // header1,header2 OR header1
        //        ^                  ^
        OwnPtr<CSPDirectiveList> policy = CSPDirectiveList::create(this, begin, position, type, source);

        // When a referrer policy has already been set, the most recent
        // one takes precedence.
        if (type != ContentSecurityPolicyHeaderTypeReport && policy->didSetReferrerPolicy())
            m_referrerPolicy = policy->referrerPolicy();

        if (!policy->allowEval(0, SuppressReport) && m_disableEvalErrorMessage.isNull())
            m_disableEvalErrorMessage = policy->evalDisabledErrorMessage();

        m_policies.append(policy.release());

        // Skip the comma, and begin the next header from the current position.
        ASSERT(position == end || *position == ',');
        skipExactly<UChar>(position, end, ',');
        begin = position;
    }
}
Пример #18
0
static String getFormatForSkeleton(const char* locale, const String& skeleton)
{
    String format = "yyyy-MM";
    UErrorCode status = U_ZERO_ERROR;
    UDateTimePatternGenerator* patternGenerator = udatpg_open(locale, &status);
    if (!patternGenerator)
        return format;
    status = U_ZERO_ERROR;
    Vector<UChar> skeletonCharacters;
    skeleton.appendTo(skeletonCharacters);
    int32_t length = udatpg_getBestPattern(patternGenerator, skeletonCharacters.data(), skeletonCharacters.size(), 0, 0, &status);
    if (status == U_BUFFER_OVERFLOW_ERROR && length) {
        StringBuffer<UChar> buffer(length);
        status = U_ZERO_ERROR;
        udatpg_getBestPattern(patternGenerator, skeletonCharacters.data(), skeletonCharacters.size(), buffer.characters(), length, &status);
        if (U_SUCCESS(status))
            format = String::adopt(buffer);
    }
    udatpg_close(patternGenerator);
    return format;
}
static void parseSourceList(CSPSourceList& sourceList, String& sources)
{
    Vector<UChar> characters;
    sources.appendTo(characters);
    sourceList.parse(characters.data(), characters.data() + characters.size());
}