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; }
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; }