Beispiel #1
0
static char* filterPosTag(const char *posTagStr, s_erc *error)
{
	S_CLR_ERR(error);
	char *filteredPosTagStr = malloc(sizeof(char) * 10);
	s_strcpy( filteredPosTagStr, posTagStr, error);

	s_bool end = FALSE;
	s_bool firstUpper = FALSE;
	int i=0;

	while( !end )
	{
		if( !firstUpper )
		{
			if( isASCIIUpper(filteredPosTagStr[i]) )
				firstUpper = TRUE;
		}
		else
		{
			if( !isASCIIUpper(filteredPosTagStr[i]) )
			{
				filteredPosTagStr[i] = '\0';
				end = TRUE;
			}
		}
		i++;
		if( filteredPosTagStr[i] == '\0' )
			end = TRUE;
	}

	return filteredPosTagStr;
}
inline bool SearchBuffer::isWordStartMatch(size_t start, size_t length) const
{
    ASSERT(m_options & AtWordStarts);

    if (!start)
        return true;

    int size = m_buffer.size();
    int offset = start;
    UChar32 firstCharacter;
    U16_GET(m_buffer.data(), 0, offset, size, firstCharacter);

    if (m_options & TreatMedialCapitalAsWordStart) {
        UChar32 previousCharacter;
        U16_PREV(m_buffer.data(), 0, offset, previousCharacter);

        if (isSeparator(firstCharacter)) {
            // The start of a separator run is a word start (".org" in "webkit.org").
            if (!isSeparator(previousCharacter))
                return true;
        } else if (isASCIIUpper(firstCharacter)) {
            // The start of an uppercase run is a word start ("Kit" in "WebKit").
            if (!isASCIIUpper(previousCharacter))
                return true;
            // The last character of an uppercase run followed by a non-separator, non-digit
            // is a word start ("Request" in "XMLHTTPRequest").
            offset = start;
            U16_FWD_1(m_buffer.data(), offset, size);
            UChar32 nextCharacter = 0;
            if (offset < size)
                U16_GET(m_buffer.data(), 0, offset, size, nextCharacter);
            if (!isASCIIUpper(nextCharacter) && !isASCIIDigit(nextCharacter) && !isSeparator(nextCharacter))
                return true;
        } else if (isASCIIDigit(firstCharacter)) {
            // The start of a digit run is a word start ("2" in "WebKit2").
            if (!isASCIIDigit(previousCharacter))
                return true;
        } else if (isSeparator(previousCharacter) || isASCIIDigit(previousCharacter)) {
            // The start of a non-separator, non-uppercase, non-digit run is a word start,
            // except after an uppercase. ("org" in "webkit.org", but not "ore" in "WebCore").
            return true;
        }
    }

    // Chinese and Japanese lack word boundary marks, and there is no clear agreement on what constitutes
    // a word, so treat the position before any CJK character as a word start.
    if (Character::isCJKIdeographOrSymbol(firstCharacter))
        return true;

    size_t wordBreakSearchStart = start + length;
    while (wordBreakSearchStart > start)
        wordBreakSearchStart = findNextWordFromIndex(m_buffer.data(), m_buffer.size(), wordBreakSearchStart, false /* backwards */);
    if (wordBreakSearchStart != start)
        return false;
    if (m_options & WholeWord)
        return static_cast<int>(start + length) == findWordEndBoundary(m_buffer.data(), m_buffer.size(), wordBreakSearchStart);
    return true;
}
static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0)
{
    if (hadPixelOrPosPrefix)
        *hadPixelOrPosPrefix = false;

    unsigned length = propertyName.length();
    if (!length)
        return String();

    StringImpl* propertyNameString = propertyName.impl();
    // If there is no uppercase character in the propertyName, there can
    // be no prefix, nor extension and we can return the same string.
    if (!containsASCIIUpperChar(*propertyNameString))
        return String(propertyNameString);

    StringBuilder builder;
    builder.reserveCapacity(length);

    unsigned i = 0;
    switch (getCSSPropertyNamePrefix(*propertyNameString)) {
    case PropertyNamePrefixNone:
        if (isASCIIUpper((*propertyNameString)[0]))
            return String();
        break;
    case PropertyNamePrefixCSS:
        i += 3;
        break;
    case PropertyNamePrefixPixel:
        i += 5;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
        break;
    case PropertyNamePrefixPos:
        i += 3;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
        break;
    case PropertyNamePrefixApple:
    case PropertyNamePrefixEpub:
    case PropertyNamePrefixKHTML:
    case PropertyNamePrefixWebKit:
        builder.append('-');
    }

    builder.append(toASCIILower((*propertyNameString)[i++]));

    for (; i < length; ++i) {
        UChar c = (*propertyNameString)[i];
        if (!isASCIIUpper(c))
            builder.append(c);
        else
            builder.append(makeString('-', toASCIILower(c)));
    }

    return builder.toString();
}
CSSPropertyID AnimationInputHelpers::keyframeAttributeToCSSPropertyID(const String& propertyName)
{
    // Disallow prefixed properties.
    if (propertyName[0] == '-' || isASCIIUpper(propertyName[0]))
        return CSSPropertyInvalid;
    if (propertyName == "cssFloat")
        return CSSPropertyFloat;
    StringBuilder builder;
    for (size_t i = 0; i < propertyName.length(); ++i) {
        if (isASCIIUpper(propertyName[i]))
            builder.append('-');
        builder.append(propertyName[i]);
    }
    return cssPropertyID(builder.toString());
}
void CombinedURLFilters::addDomain(uint64_t actionId, const String& domain)
{
    // This is like adding (.|^)domain$ by adding two Vector<Term>'s,
    // but interpreting domain as a series of characters, not a regular expression.
    // This way a domain of "webkit.org" will match "bugs.webkit.org" and "webkit.org".
    // FIXME: Add support for matching only subdomains or no subdomains.
    Vector<Term> prependDot;
    Vector<Term> prependBeginningOfLine;
    prependDot.reserveInitialCapacity(domain.length() + 3);
    prependBeginningOfLine.reserveInitialCapacity(domain.length() + 1); // This is just no .* at the beginning.
    
    Term canonicalDotStar(Term::UniversalTransition);
    canonicalDotStar.quantify(AtomQuantifier::ZeroOrMore);
    prependDot.uncheckedAppend(canonicalDotStar);
    prependDot.uncheckedAppend(Term('.', true));
    
    for (unsigned i = 0; i < domain.length(); i++) {
        ASSERT(isASCII(domain[i]));
        ASSERT(!isASCIIUpper(domain[i]));
        prependDot.uncheckedAppend(Term(domain[i], true));
        prependBeginningOfLine.uncheckedAppend(Term(domain[i], true));
    }
    prependDot.uncheckedAppend(Term::EndOfLineAssertionTerm);
    prependBeginningOfLine.uncheckedAppend(Term::EndOfLineAssertionTerm);
    
    addPattern(actionId, prependDot);
    addPattern(actionId, prependBeginningOfLine);
}
static inline bool matchesCSSPropertyNamePrefix(const StringImpl& propertyName, const char (&prefix)[prefixCStringLength])
{
    size_t prefixLength = prefixCStringLength - 1;

    ASSERT(toASCIILower(propertyName[0]) == prefix[0]);
    const size_t offset = 1;

#ifndef NDEBUG
    for (size_t i = 0; i < prefixLength; ++i)
        ASSERT(isASCIILower(prefix[i]));
    ASSERT(!prefix[prefixLength]);
    ASSERT(propertyName.length());
#endif

    // The prefix within the property name must be followed by a capital letter.
    // Other characters in the prefix within the property name must be lowercase.
    if (propertyName.length() < (prefixLength + 1))
        return false;

    for (size_t i = offset; i < prefixLength; ++i) {
        if (propertyName[i] != prefix[i])
            return false;
    }

    if (!isASCIIUpper(propertyName[prefixLength]))
        return false;
    return true;
}
static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0)
{
    if (hadPixelOrPosPrefix)
        *hadPixelOrPosPrefix = false;

    unsigned length = propertyName.size();
    if (!length)
        return String();

    Vector<UChar> name;
    name.reserveInitialCapacity(length);

    unsigned i = 0;

    if (hasCSSPropertyNamePrefix(propertyName, "css"))
        i += 3;
    else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
        i += 5;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
    } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
        i += 3;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
    } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
            || hasCSSPropertyNamePrefix(propertyName, "khtml")
            || hasCSSPropertyNamePrefix(propertyName, "apple"))
        name.append('-');
    else {
        if (isASCIIUpper(propertyName.data()[0]))
            return String();
    }

    name.append(toASCIILower(propertyName.data()[i++]));

    for (; i < length; ++i) {
        UChar c = propertyName.data()[i];
        if (!isASCIIUpper(c))
            name.append(c);
        else {
            name.append('-');
            name.append(toASCIILower(c));
        }
    }

    return String::adopt(name);
}
static String cssPropertyName(const Identifier& propertyName, bool* hadPixelOrPosPrefix = 0)
{
    if (hadPixelOrPosPrefix)
        *hadPixelOrPosPrefix = false;

    unsigned length = propertyName.length();
    if (!length)
        return String();

    StringBuilder builder;
    builder.reserveCapacity(length);

    unsigned i = 0;

    if (hasCSSPropertyNamePrefix(propertyName, "css"))
        i += 3;
    else if (hasCSSPropertyNamePrefix(propertyName, "pixel")) {
        i += 5;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
    } else if (hasCSSPropertyNamePrefix(propertyName, "pos")) {
        i += 3;
        if (hadPixelOrPosPrefix)
            *hadPixelOrPosPrefix = true;
    } else if (hasCSSPropertyNamePrefix(propertyName, "webkit")
            || hasCSSPropertyNamePrefix(propertyName, "khtml")
            || hasCSSPropertyNamePrefix(propertyName, "apple")
            || hasCSSPropertyNamePrefix(propertyName, "epub"))
        builder.append('-');
    else {
        if (isASCIIUpper(propertyName.characters()[0]))
            return String();
    }

    builder.append(toASCIILower(propertyName.characters()[i++]));

    for (; i < length; ++i) {
        UChar c = propertyName.characters()[i];
        if (!isASCIIUpper(c))
            builder.append(c);
        else
            builder.append(makeString('-', toASCIILower(c)));
    }

    return builder.toString();
}
static inline bool containsASCIIUpperChar(const CharacterType* string, size_t length)
{
    for (unsigned i = 0; i < length; ++i) {
        if (isASCIIUpper(string[i]))
            return true;
    }
    return false;
}
static bool containsOnlyASCIIWithNoUppercase(const String& domain)
{
    for (unsigned i = 0; i < domain.length(); ++i) {
        UChar c = domain.at(i);
        if (!isASCII(c) || isASCIIUpper(c))
            return false;
    }
    return true;
}
static DateTimeFormat::FieldType mapCharacterToFieldType(const UChar ch)
{
    if (isASCIIUpper(ch))
        return upperCaseToFieldTypeMap[ch - 'A'];

    if (isASCIILower(ch))
        return lowerCaseToFieldTypeMap[ch - 'a'];

    return DateTimeFormat::FieldTypeLiteral;
}
static inline bool hasNonASCIIOrUpper(const CharacterType* characters, unsigned length)
{
    bool hasUpper = false;
    CharacterType ored = 0;
    for (unsigned i = 0; i < length; i++) {
        CharacterType c = characters[i];
        hasUpper |= isASCIIUpper(c);
        ored |= c;
    }
    return hasUpper || (ored & ~0x7F);
}
static bool isValidAttributeName(const String& name)
{
    if (!name.startsWith("data-"))
        return false;

    unsigned length = name.length();
    for (unsigned i = 5; i < length; ++i) {
        if (isASCIIUpper(name[i]))
            return false;
    }

    return true;
}
Beispiel #14
0
static bool hasNonASCIIOrUpper(const String& string)
{
    const UChar* characters = string.characters();
    unsigned length = string.length();
    bool hasUpper = false;
    UChar ored = 0;
    for (unsigned i = 0; i < length; i++) {
        UChar c = characters[i];
        hasUpper |= isASCIIUpper(c);
        ored |= c;
    }
    return hasUpper || (ored & ~0x7F);
}
// This returns an AtomicString because attribute names are always stored
// as AtomicString types in Element (see setAttribute()).
static AtomicString convertPropertyNameToAttributeName(const String& name)
{
    StringBuilder builder;
    builder.appendLiteral("data-");

    unsigned length = name.length();
    for (unsigned i = 0; i < length; ++i) {
        UChar character = name[i];
        if (isASCIIUpper(character)) {
            builder.append('-');
            builder.append(toASCIILower(character));
        } else
            builder.append(character);
    }

    return builder.toAtomicString();
}
// Check for a CSS prefix.
// Passed prefix is all lowercase.
// First character of the prefix within the property name may be upper or lowercase.
// Other characters in the prefix within the property name must be lowercase.
// The prefix within the property name must be followed by a capital letter.
static bool hasCSSPropertyNamePrefix(const Identifier& propertyName, const char* prefix)
{
#ifndef NDEBUG
    ASSERT(*prefix);
    for (const char* p = prefix; *p; ++p)
        ASSERT(isASCIILower(*p));
    ASSERT(propertyName.size());
#endif

    if (toASCIILower(propertyName.data()[0]) != prefix[0])
        return false;

    unsigned length = propertyName.size();
    for (unsigned i = 1; i < length; ++i) {
        if (!prefix[i])
            return isASCIIUpper(propertyName.data()[i]);
        if (propertyName.data()[i] != prefix[i])
            return false;
    }
    return false;
}
static String convertPropertyNameToAttributeName(const String& name)
{
    Vector<UChar> newStringBuffer;

    newStringBuffer.append('d');
    newStringBuffer.append('a');
    newStringBuffer.append('t');
    newStringBuffer.append('a');
    newStringBuffer.append('-');

    const UChar* characters = name.characters();
    unsigned length = name.length();
    for (unsigned i = 0; i < length; ++i) {
        if (isASCIIUpper(characters[i])) {
            newStringBuffer.append('-');
            newStringBuffer.append(toASCIILower(characters[i]));
        } else
            newStringBuffer.append(characters[i]);
    }

    return String::adopt(newStringBuffer);
}
static CSSPropertyInfo cssPropertyIDForJSCSSPropertyName(PropertyName propertyName)
{
    CSSPropertyInfo propertyInfo = {CSSPropertyInvalid, false};
    bool hadPixelOrPosPrefix = false;

    StringImpl* propertyNameString = propertyName.publicName();
    if (!propertyNameString)
        return propertyInfo;
    unsigned length = propertyNameString->length();
    if (!length)
        return propertyInfo;

    String stringForCache = String(propertyNameString);
    typedef HashMap<String, CSSPropertyInfo> CSSPropertyInfoMap;
    static NeverDestroyed<CSSPropertyInfoMap> propertyInfoCache;
    propertyInfo = propertyInfoCache.get().get(stringForCache);
    if (propertyInfo.propertyID)
        return propertyInfo;

    const size_t bufferSize = maxCSSPropertyNameLength + 1;
    char buffer[bufferSize];
    char* bufferPtr = buffer;
    const char* name = bufferPtr;

    unsigned i = 0;
    // Prefixes CSS, Pixel, Pos are ignored.
    // Prefixes Apple, KHTML and Webkit are transposed to "-webkit-".
    // The prefix "Epub" becomes "-epub-".
    switch (getCSSPropertyNamePrefix(*propertyNameString)) {
    case PropertyNamePrefixNone:
        if (isASCIIUpper((*propertyNameString)[0]))
            return propertyInfo;
        break;
    case PropertyNamePrefixCSS:
        i += 3;
        break;
    case PropertyNamePrefixPixel:
        i += 5;
        hadPixelOrPosPrefix = true;
        break;
    case PropertyNamePrefixPos:
        i += 3;
        hadPixelOrPosPrefix = true;
        break;
#if ENABLE(LEGACY_CSS_VENDOR_PREFIXES)
    case PropertyNamePrefixApple:
    case PropertyNamePrefixKHTML:
        ASSERT(RuntimeEnabledFeatures::sharedFeatures().legacyCSSVendorPrefixesEnabled());
        writeWebKitPrefix(bufferPtr);
        i += 5;
        break;
#endif
    case PropertyNamePrefixEpub:
        writeEpubPrefix(bufferPtr);
        i += 4;
        break;
    case PropertyNamePrefixWebKit:
        writeWebKitPrefix(bufferPtr);
        i += 6;
        break;
    }

    *bufferPtr++ = toASCIILower((*propertyNameString)[i++]);

    char* bufferEnd = buffer + bufferSize;
    char* stringEnd = bufferEnd - 1;
    size_t bufferSizeLeft = stringEnd - bufferPtr;
    size_t propertySizeLeft = length - i;
    if (propertySizeLeft > bufferSizeLeft)
        return propertyInfo;

    for (; i < length; ++i) {
        UChar c = (*propertyNameString)[i];
        if (!c || c >= 0x7F)
            return propertyInfo; // illegal character
        if (isASCIIUpper(c)) {
            size_t bufferSizeLeft = stringEnd - bufferPtr;
            size_t propertySizeLeft = length - i + 1;
            if (propertySizeLeft > bufferSizeLeft)
                return propertyInfo;
            *bufferPtr++ = '-';
            *bufferPtr++ = toASCIILower(c);
        } else
            *bufferPtr++ = c;
        ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
    }
    ASSERT_WITH_SECURITY_IMPLICATION(bufferPtr < bufferEnd);
    *bufferPtr = '\0';

    unsigned outputLength = bufferPtr - buffer;
#if PLATFORM(IOS)
    cssPropertyNameIOSAliasing(buffer, name, outputLength);
#endif

    const Property* hashTableEntry = findProperty(name, outputLength);
    int propertyID = hashTableEntry ? hashTableEntry->id : 0;
    if (propertyID) {
        propertyInfo.hadPixelOrPosPrefix = hadPixelOrPosPrefix;
        propertyInfo.propertyID = static_cast<CSSPropertyID>(propertyID);
        propertyInfoCache.get().add(stringForCache, propertyInfo);
    }
    return propertyInfo;
}