Finish auditing call sites of upper() and lower(), eliminate many, and rename the...
authordarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Feb 2016 23:18:47 +0000 (23:18 +0000)
committerdarin@apple.com <darin@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 6 Feb 2016 23:18:47 +0000 (23:18 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153905

Reviewed by Sam Weinig.

Source/JavaScriptCore:

* runtime/IntlObject.cpp:
(JSC::canonicalLangTag): Use converToASCIIUppercase on the language tag.

* runtime/StringPrototype.cpp:
(JSC::stringProtoFuncToLowerCase): Tweak style and update for name change.
(JSC::stringProtoFuncToUpperCase): Ditto.

Source/WebCore:

* Modules/mediasource/MediaSource.cpp:
(WebCore::MediaSource::isTypeSupported): Use convertToASCIILowercase on MIME type.

* accessibility/AccessibilityObject.cpp:
(WebCore::AccessibilityObject::selectText): Use new names for lower and upper. Also
tweaked style a tiny bit and used u_toupper rather than converting an entire
string to uppercase.

* dom/Document.cpp:
(WebCore::Document::addImageElementByCaseFoldedUsemap): Renamed to reflect the use
of case folding rather than lowercasing.
(WebCore::Document::removeImageElementByCaseFoldedUsemap): Ditto.
(WebCore::Document::imageElementByCaseFoldedUsemap): Ditto.
* dom/Document.h: Ditto.
* dom/DocumentOrderedMap.cpp:
(WebCore::DocumentOrderedMap::getElementByCaseFoldedMapName): Ditto.
(WebCore::DocumentOrderedMap::getElementByCaseFoldedUsemap): Ditto.
* dom/DocumentOrderedMap.h: Ditto.

* dom/TreeScope.cpp:
(WebCore::TreeScope::getImageMap): Removed unneeded special case for null string.
Simplified logic for cases where the URL does not have a "#" character in it.
Use case folding instead of lowercase.

* editing/cocoa/HTMLConverter.mm:
(HTMLConverter::_processText): Removed unneded special case for the empty string.
Use makCapitalized instead of Cocoa function for "capitalize". Use upper and lower
functions by their new names.

* html/HTMLImageElement.cpp:
(WebCore::HTMLImageElement::parseAttribute): Use case folding instead of
lowerasing for the usemap attribute.
(WebCore::HTMLImageElement::insertedInto): Ditto.
(WebCore::HTMLImageElement::removedFrom): Ditto.
(WebCore::HTMLImageElement::matchesCaseFoldedUsemap): Ditto.
* html/HTMLImageElement.h: Rename since usemap is case folded now, not lowercased.

* html/HTMLMapElement.cpp:
(WebCore::HTMLMapElement::imageElement): Use case folding instead of lowercasing
for usemap.
(WebCore::HTMLMapElement::parseAttribute): Ditto.

* platform/Language.cpp:
(WebCore::canonicalLanguageIdentifier): Use convertToASCIILowercase for language code.
(WebCore::indexOfBestMatchingLanguageInList): Ditto.

* platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
(WebCore::HarfBuzzShaper::shapeHarfBuzzRuns): Use new name for the upper function.

* platform/network/HTTPParsers.cpp:
(WebCore::parseContentTypeOptionsHeader): Use equalLettersIgnoringASCIICase instead
of lowercasing to check for a specific header value.

* platform/network/MIMEHeader.cpp:
(WebCore::retrieveKeyValuePairs): Use convertToASCIILowercase for MIME header name.
(WebCore::MIMEHeader::parseContentTransferEncoding): Use equalLettersIgnoringASCIICase
instead of lowercasing.

* platform/network/cf/ResourceHandleCFNet.cpp:
(WebCore::allowsAnyHTTPSCertificateHosts): Make this hash ASCII case-insensitive.
(WebCore::clientCertificates): Ditto.
(WebCore::ResourceHandle::createCFURLConnection): Remove call to lower since the
set is now ASCII case-insensitive.
(WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Ditto.
(WebCore::ResourceHandle::setClientCertificate): Ditto.

* platform/network/curl/CookieJarCurl.cpp:
(WebCore::getNetscapeCookieFormat): Use equalLettersIgnoringASCIICase instead of
lowercasing.

* platform/network/curl/MultipartHandle.cpp:
(WebCore::MultipartHandle::didReceiveResponse): Use convertToASCIILowercase to
make a MIME type lowercase.

* platform/network/curl/ResourceHandleCurl.cpp:
(WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Removed unneeded
conversion to lowercase now that the set is ASCII case-insensitive.
(WebCore::ResourceHandle::setClientCertificate): Removed code that populates a map
that is then never used for anything.

* platform/network/curl/ResourceHandleManager.cpp:
(WebCore::headerCallback): Use convertToASCIILowercase for MIME type.

* platform/network/curl/SSLHandle.cpp: Made hash maps keyed by host names
ASCII case-insensitive.
(WebCore::addAllowedClientCertificate): Removed lowercasing since the map itself
is now ASCII case insensitve.
(WebCore::setSSLClientCertificate): Ditto. Also use auto for iterator type so we
don't have to write out the map type.
(WebCore::sslIgnoreHTTPSCertificate): Ditto.
(WebCore::certVerifyCallback): Ditto.

* platform/network/soup/ResourceHandleSoup.cpp: Made hash maps keyed by host names
ASCII case-insensitive.
(WebCore::allowsAnyHTTPSCertificateHosts): Ditto.
(WebCore::handleUnignoredTLSErrors): Ditto.
(WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Ditto.
(WebCore::ResourceHandle::setClientCertificate): Ditto.

* platform/text/LocaleToScriptMappingDefault.cpp: Made hash maps keyed by script
names ASCII case-insensitive. USE WTF_ARRAY_LENGTH as appropriate.
(WebCore::scriptNameToCode): Use modern style to initialize the map. Removed
unnecessary lowercasing of the script name before looking at the map.
(WebCore::localeToScriptCodeForFontSelection): Ditto.

* platform/text/win/LocaleWin.cpp:
(WebCore::convertLocaleNameToLCID): Made map ASCII case-insensitive and removed
unneeded lowercasing.

* platform/win/PasteboardWin.cpp:
(WebCore::clipboardTypeFromMIMEType): Use equalLettersIgnoringASCIICase instead
of lowercasing.

* rendering/RenderText.cpp:
(WebCore::applyTextTransform): Use new names for the upper and lower functions.

* xml/XMLHttpRequest.cpp:
(WebCore::XMLHttpRequest::responseIsXML): Remove unneeded lowercasing, since
DOMImplementation now has ASCII case-insensitive handling of MIME types.

Source/WebKit/mac:

* Plugins/WebBasePluginPackage.mm:
(-[WebBasePluginPackage getPluginInfoFromPLists]): Use modern for loops.
(-[WebBasePluginPackage supportsExtension:]): Use convertToASCIILowercase for extension assert.
Also use modern for loop.
(-[WebBasePluginPackage supportsMIMEType:]): Ditto.
(-[WebBasePluginPackage MIMETypeForExtension:]): Ditto.

Source/WebKit/win:

* Plugins/PluginDatabase.cpp:
(WebCore::PluginDatabase::pluginForMIMEType): Use ASCII case-insensitive map rather
than lowercasing the MIME type.
(WebCore::PluginDatabase::setPreferredPluginForMIMEType): Ditto.

* Plugins/PluginDatabase.h: Make m_preferredPlugins use an ASCII case-insensitive hash.

* Plugins/PluginPackage.h: Use ASCII case-insensitive hash for maps keyed by MIME type.

* Plugins/PluginPackageWin.cpp:
(WebCore::PluginPackage::fetchInfo): Use convertToASCIILowercase to lowercase a MIME type.

Source/WebKit2:

* NetworkProcess/CustomProtocols/CustomProtocolManager.h: Use ASCII case-insensitive hash
for set of registered schemes.

* Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm:
(WebKit::getPluginInfoFromPropertyLists): Use convertToASCIILowercase for MIME type and
for file extensions.

* Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
(WebKit::NetscapePluginModule::parseMIMEDescription): Use convertToASCIILowercase for
MIME description.

* UIProcess/API/efl/ewk_context.cpp:
(ewk_context_preferred_languages_set): Use convertToASCIILowercase for language.

* UIProcess/API/gtk/WebKitWebContext.cpp:
(webkit_web_context_set_preferred_languages): Use convertToASCIILowercase for language.

* UIProcess/Plugins/PluginInfoStore.cpp:
(WebKit::PluginInfoStore::findPluginForExtension): Use Vector::contains instead of
writing it out using std::find.
(WebKit::pathExtension): Lowercase the result with convertToASCIILowercase instead of
leaving that to the caller.
(WebKit::PluginInfoStore::findPlugin): Removed call to lower since pathExtension
handles that now.

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::findPlugin): Use convertToASCIILowercase for MIME type.

* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::globalURLSchemesWithCustomProtocolHandlers): Use
an ASCII case-insensitive hash.
(WebKit::WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers):
Remove lowercasing, since the hash is now ASCII case-insensitive.
(WebKit::WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers):
Ditto.

* UIProcess/WebProcessPool.h: Use an ASCII case-insensitive hash.

* WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
(WebKit::NetscapePlugin::initialize): Use convertToASCIILowercase on parameter names
and values.

* WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
(WebKit::pluginSupportsExtension): Use convertToASCIILowercase for extension assertion.
Also use a modern for loop.
(WebKit::WebFrameLoaderClient::objectContentType): Make the checks for empty MIME types
a little less redundant. Reordered logic to avoid checking the list of supported MIME
types extra times, and to eliminate the need for a boolean. Use convertToASCIILowercase
on the extension.

Source/WTF:

* wtf/text/AtomicString.cpp:
(WTF::AtomicString::lower): Deleted.
* wtf/text/AtomicString.h: Deleted the lower function.

* wtf/text/StringImpl.cpp:
(WTF::StringImpl::convertToLowercaseWithoutLocale): Renamed from lower.
(WTF::StringImpl::convertToUppercaseWithoutLocale): Renamed from upper.
(WTF::StringImpl::convertToLowercaseWithLocale): Renamed from lower.
(WTF::StringImpl::convertToUppercaseWithLocale): Renamed from upper.
(WTF::StringImpl::foldCase): Added fast cases for ASCII since this is
now used in some more-performance-critical code.
* wtf/text/StringImpl.h: Renamed lower and upper.

* wtf/text/WTFString.cpp:
(WTF::String::convertToLowercaseWithoutLocale): Renamed from lower.
(WTF::String::convertToUppercaseWithoutLocale): Renamed from upper.
(WTF::String::convertToLowercaseWithLocale): Renamed from lower.
(WTF::String::convertToUppercaseWithLocale): Renamed from upper.
* wtf/text/WTFString.h: Renamed lower and upper. Removed unneeded comment.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@196223 268f45cc-cd09-0410-ab3c-d52691b4dbfc

57 files changed:
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/runtime/IntlObject.cpp
Source/JavaScriptCore/runtime/StringPrototype.cpp
Source/WTF/ChangeLog
Source/WTF/wtf/text/AtomicString.cpp
Source/WTF/wtf/text/AtomicString.h
Source/WTF/wtf/text/StringImpl.cpp
Source/WTF/wtf/text/StringImpl.h
Source/WTF/wtf/text/WTFString.cpp
Source/WTF/wtf/text/WTFString.h
Source/WebCore/ChangeLog
Source/WebCore/Modules/mediasource/MediaSource.cpp
Source/WebCore/accessibility/AccessibilityObject.cpp
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/dom/DocumentOrderedMap.cpp
Source/WebCore/dom/DocumentOrderedMap.h
Source/WebCore/dom/TreeScope.cpp
Source/WebCore/editing/cocoa/HTMLConverter.mm
Source/WebCore/html/HTMLImageElement.cpp
Source/WebCore/html/HTMLImageElement.h
Source/WebCore/html/HTMLMapElement.cpp
Source/WebCore/platform/Language.cpp
Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp
Source/WebCore/platform/network/HTTPParsers.cpp
Source/WebCore/platform/network/MIMEHeader.cpp
Source/WebCore/platform/network/cf/ResourceHandleCFNet.cpp
Source/WebCore/platform/network/curl/CookieJarCurl.cpp
Source/WebCore/platform/network/curl/MultipartHandle.cpp
Source/WebCore/platform/network/curl/ResourceHandleCurl.cpp
Source/WebCore/platform/network/curl/ResourceHandleManager.cpp
Source/WebCore/platform/network/curl/SSLHandle.cpp
Source/WebCore/platform/network/soup/ResourceHandleSoup.cpp
Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp
Source/WebCore/platform/text/win/LocaleWin.cpp
Source/WebCore/platform/win/PasteboardWin.cpp
Source/WebCore/rendering/RenderText.cpp
Source/WebCore/xml/XMLHttpRequest.cpp
Source/WebKit/mac/ChangeLog
Source/WebKit/mac/Plugins/WebBasePluginPackage.mm
Source/WebKit/win/ChangeLog
Source/WebKit/win/Plugins/PluginDatabase.cpp
Source/WebKit/win/Plugins/PluginDatabase.h
Source/WebKit/win/Plugins/PluginPackage.h
Source/WebKit/win/Plugins/PluginPackageWin.cpp
Source/WebKit2/ChangeLog
Source/WebKit2/NetworkProcess/CustomProtocols/CustomProtocolManager.h
Source/WebKit2/Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm
Source/WebKit2/Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp
Source/WebKit2/UIProcess/API/efl/ewk_context.cpp
Source/WebKit2/UIProcess/API/gtk/WebKitWebContext.cpp
Source/WebKit2/UIProcess/Plugins/PluginInfoStore.cpp
Source/WebKit2/UIProcess/WebPageProxy.cpp
Source/WebKit2/UIProcess/WebProcessPool.cpp
Source/WebKit2/UIProcess/WebProcessPool.h
Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp
Source/WebKit2/WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp

index 1ac6fca..4bb6675 100644 (file)
@@ -1,3 +1,17 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * runtime/IntlObject.cpp:
+        (JSC::canonicalLangTag): Use converToASCIIUppercase on the language tag.
+
+        * runtime/StringPrototype.cpp:
+        (JSC::stringProtoFuncToLowerCase): Tweak style and update for name change.
+        (JSC::stringProtoFuncToUpperCase): Ditto.
+
 2016-02-06  Chris Dumez  <cdumez@apple.com>
 
         Object.getOwnPropertyDescriptor() does not work on sub-frame's window
index f98cd54..9e8f033 100644 (file)
@@ -322,7 +322,7 @@ static String canonicalLangTag(const Vector<String>& parts)
         if (isValidRegion) {
             ++currentIndex;
             canonical.append('-');
-            canonical.append(region.upper());
+            canonical.append(region.convertToASCIIUppercase());
         }
     }
 
index 2d502b0..d5dcdbb 100644 (file)
@@ -1406,17 +1406,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToLowerCase(ExecState* exec)
         return throwVMTypeError(exec);
     JSString* sVal = thisValue.toString(exec);
     const String& s = sVal->value(exec);
-
-    int sSize = s.length();
-    if (!sSize)
-        return JSValue::encode(sVal);
-    RELEASE_ASSERT(sSize >= 0);
-
-    StringImpl* ourImpl = s.impl();
-    RefPtr<StringImpl> lower = ourImpl->lower();
-    if (ourImpl == lower)
+    String lowercasedString = s.convertToLowercaseWithoutLocale();
+    if (lowercasedString.impl() == s.impl())
         return JSValue::encode(sVal);
-    return JSValue::encode(jsString(exec, String(lower.release())));
+    return JSValue::encode(jsString(exec, lowercasedString));
 }
 
 EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec)
@@ -1426,16 +1419,10 @@ EncodedJSValue JSC_HOST_CALL stringProtoFuncToUpperCase(ExecState* exec)
         return throwVMTypeError(exec);
     JSString* sVal = thisValue.toString(exec);
     const String& s = sVal->value(exec);
-
-    int sSize = s.length();
-    if (!sSize)
-        return JSValue::encode(sVal);
-
-    StringImpl* sImpl = s.impl();
-    RefPtr<StringImpl> upper = sImpl->upper();
-    if (sImpl == upper)
+    String uppercasedString = s.convertToUppercaseWithoutLocale();
+    if (uppercasedString.impl() == s.impl())
         return JSValue::encode(sVal);
-    return JSValue::encode(jsString(exec, String(upper.release())));
+    return JSValue::encode(jsString(exec, uppercasedString));
 }
 
 EncodedJSValue JSC_HOST_CALL stringProtoFuncLocaleCompare(ExecState* exec)
index 9097613..a8547fd 100644 (file)
@@ -1,3 +1,30 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * wtf/text/AtomicString.cpp:
+        (WTF::AtomicString::lower): Deleted.
+        * wtf/text/AtomicString.h: Deleted the lower function.
+
+        * wtf/text/StringImpl.cpp:
+        (WTF::StringImpl::convertToLowercaseWithoutLocale): Renamed from lower.
+        (WTF::StringImpl::convertToUppercaseWithoutLocale): Renamed from upper.
+        (WTF::StringImpl::convertToLowercaseWithLocale): Renamed from lower.
+        (WTF::StringImpl::convertToUppercaseWithLocale): Renamed from upper.
+        (WTF::StringImpl::foldCase): Added fast cases for ASCII since this is
+        now used in some more-performance-critical code.
+        * wtf/text/StringImpl.h: Renamed lower and upper.
+
+        * wtf/text/WTFString.cpp:
+        (WTF::String::convertToLowercaseWithoutLocale): Renamed from lower.
+        (WTF::String::convertToUppercaseWithoutLocale): Renamed from upper.
+        (WTF::String::convertToLowercaseWithLocale): Renamed from lower.
+        (WTF::String::convertToUppercaseWithLocale): Renamed from upper.
+        * wtf/text/WTFString.h: Renamed lower and upper. Removed unneeded comment.
+
 2016-02-03  Darin Adler  <darin@apple.com>
 
         Convert another batch of String::lower callsites to something better, typically convertToASCIILowercase
index 99e0d6e..a9fef15 100644 (file)
 
 namespace WTF {
 
-AtomicString AtomicString::lower() const
-{
-    // Note: This is a hot function in the Dromaeo benchmark.
-    StringImpl* impl = this->impl();
-    if (UNLIKELY(!impl))
-        return AtomicString();
-
-    RefPtr<StringImpl> lowercasedString = impl->lower();
-    if (LIKELY(lowercasedString == impl))
-        return *this;
-
-    AtomicString result;
-    result.m_string = AtomicStringImpl::add(lowercasedString.get());
-    return result;
-}
-
 template<AtomicString::CaseConvertType type>
 ALWAYS_INLINE AtomicString AtomicString::convertASCIICase() const
 {
index a9e4069..abbdb45 100644 (file)
@@ -155,7 +155,6 @@ public:
 
     WTF_EXPORT_STRING_API AtomicString convertToASCIILowercase() const;
     WTF_EXPORT_STRING_API AtomicString convertToASCIIUppercase() const;
-    WTF_EXPORT_STRING_API AtomicString lower() const;
 
     int toInt(bool* ok = 0) const { return m_string.toInt(ok); }
     double toDouble(bool* ok = 0) const { return m_string.toDouble(ok); }
index cb3d024..7f79489 100644 (file)
@@ -361,9 +361,9 @@ UChar32 StringImpl::characterStartingAt(unsigned i)
     return 0;
 }
 
-Ref<StringImpl> StringImpl::lower()
+Ref<StringImpl> StringImpl::convertToLowercaseWithoutLocale()
 {
-    // Note: This is a hot function in the Dromaeo benchmark, specifically the
+    // Note: At one time this was a hot function in the Dromaeo benchmark, specifically the
     // no-op code path up through the first 'return' statement.
 
     // First scan the string for uppercase and non-ASCII characters:
@@ -442,11 +442,12 @@ SlowPath:
     return newImpl.releaseNonNull();
 }
 
-Ref<StringImpl> StringImpl::upper()
+Ref<StringImpl> StringImpl::convertToUppercaseWithoutLocale()
 {
-    // This function could be optimized for no-op cases the way lower() is,
-    // but in empirical testing, few actual calls to upper() are no-ops, so
-    // it wouldn't be worth the extra time for pre-scanning.
+    // This function could be optimized for no-op cases the way
+    // convertToLowercaseWithoutLocale() is, but in empirical testing,
+    // few actual calls to upper() are no-ops, so it wouldn't be worth
+    // the extra time for pre-scanning.
 
     if (m_length > static_cast<unsigned>(std::numeric_limits<int32_t>::max()))
         CRASH();
@@ -477,7 +478,7 @@ Ref<StringImpl> StringImpl::upper()
         int numberSharpSCharacters = 0;
 
         // There are two special cases.
-        //  1. latin-1 characters when converted to upper case are 16 bit characters.
+        //  1. Some Latin-1 characters when converted to upper case are 16 bit characters.
         //  2. Lower case sharp-S converts to "SS" (two characters)
         for (int32_t i = 0; i < length; ++i) {
             LChar c = m_data8[i];
@@ -485,7 +486,7 @@ Ref<StringImpl> StringImpl::upper()
                 ++numberSharpSCharacters;
             ASSERT(u_toupper(c) <= 0xFFFF);
             UChar upper = u_toupper(c);
-            if (UNLIKELY(upper > 0xff)) {
+            if (UNLIKELY(upper > 0xFF)) {
                 // Since this upper-cased character does not fit in an 8-bit string, we need to take the 16-bit path.
                 goto upconvert;
             }
@@ -554,14 +555,14 @@ static inline bool needsTurkishCasingRules(const AtomicString& localeIdentifier)
         && (localeIdentifier.length() == 2 || localeIdentifier[2] == '-');
 }
 
-Ref<StringImpl> StringImpl::lower(const AtomicString& localeIdentifier)
+Ref<StringImpl> StringImpl::convertToLowercaseWithLocale(const AtomicString& localeIdentifier)
 {
     // Use the more-optimized code path most of the time.
     // Assuming here that the only locale-specific lowercasing is the Turkish casing rules.
     // FIXME: Could possibly optimize further by looking for the specific sequences
     // that have locale-specific lowercasing. There are only three of them.
     if (!needsTurkishCasingRules(localeIdentifier))
-        return lower();
+        return convertToLowercaseWithoutLocale();
 
     // FIXME: Could share more code with the main StringImpl::lower by factoring out
     // this last part into a shared function that takes a locale string, since this is
@@ -590,13 +591,13 @@ Ref<StringImpl> StringImpl::lower(const AtomicString& localeIdentifier)
     return newString.releaseNonNull();
 }
 
-Ref<StringImpl> StringImpl::upper(const AtomicString& localeIdentifier)
+Ref<StringImpl> StringImpl::convertToUppercaseWithLocale(const AtomicString& localeIdentifier)
 {
     // Use the more-optimized code path most of the time.
     // Assuming here that the only locale-specific lowercasing is the Turkish casing rules,
     // and that the only affected character is lowercase "i".
     if (!needsTurkishCasingRules(localeIdentifier) || find('i') == notFound)
-        return upper();
+        return convertToUppercaseWithoutLocale();
 
     if (m_length > static_cast<unsigned>(std::numeric_limits<int32_t>::max()))
         CRASH();
@@ -623,60 +624,86 @@ Ref<StringImpl> StringImpl::upper(const AtomicString& localeIdentifier)
 
 Ref<StringImpl> StringImpl::foldCase()
 {
-    // FIXME: Why doesn't this function have a preflight like the one in StringImpl::lower?
-
-    if (m_length > static_cast<unsigned>(std::numeric_limits<int32_t>::max()))
-        CRASH();
-    int32_t length = m_length;
-
     if (is8Bit()) {
-        // Do a faster loop for the case where all the characters are ASCII.
-        LChar* data;
-        auto newImpl = createUninitialized(m_length, data);
-        LChar ored = 0;
-
-        for (int32_t i = 0; i < length; ++i) {
-            LChar c = m_data8[i];
-            data[i] = toASCIILower(c);
-            ored |= c;
+        unsigned failingIndex;
+        for (unsigned i = 0; i < m_length; ++i) {
+            auto character = m_data8[i];
+            if (UNLIKELY(!isASCII(character) || isASCIIUpper(character))) {
+                failingIndex = i;
+                goto SlowPath;
+            }
         }
+        // String was all ASCII and no uppercase, so just return as-is.
+        return *this;
 
-        if (!(ored & ~0x7F))
-            return newImpl;
-
-        // Do a slower implementation for cases that include non-ASCII Latin-1 characters.
-        // FIXME: Shouldn't this use u_foldCase instead of u_tolower?
-        for (int32_t i = 0; i < length; ++i) {
-            ASSERT(u_tolower(m_data8[i]) <= 0xFF);
-            data[i] = static_cast<LChar>(u_tolower(m_data8[i]));
+SlowPath:
+        bool need16BitCharacters = false;
+        for (unsigned i = failingIndex; i < m_length; ++i) {
+            auto character = m_data8[i];
+            if (character == 0xB5 || character == 0xDF) {
+                need16BitCharacters = true;
+                break;
+            }
         }
 
-        return newImpl;
+        if (!need16BitCharacters) {
+            LChar* data8;
+            auto folded = createUninitializedInternalNonEmpty(m_length, data8);
+            for (unsigned i = 0; i < failingIndex; ++i)
+                data8[i] = m_data8[i];
+            for (unsigned i = failingIndex; i < m_length; ++i) {
+                auto character = m_data8[i];
+                if (isASCII(character))
+                    data8[i] = toASCIILower(character);
+                else {
+                    ASSERT(u_foldCase(character, U_FOLD_CASE_DEFAULT) <= 0xFF);
+                    data8[i] = static_cast<LChar>(u_foldCase(character, U_FOLD_CASE_DEFAULT));
+                }
+            }
+            return folded;
+        }
+    } else {
+        // FIXME: Unclear why we use goto in the 8-bit case, and a different approach in the 16-bit case.
+        bool noUpper = true;
+        unsigned ored = 0;
+        for (unsigned i = 0; i < m_length; ++i) {
+            UChar character = m_data16[i];
+            if (UNLIKELY(isASCIIUpper(character)))
+                noUpper = false;
+            ored |= character;
+        }
+        if (!(ored & ~0x7F)) {
+            if (noUpper) {
+                // String was all ASCII and no uppercase, so just return as-is.
+                return *this;
+            }
+            UChar* data16;
+            auto folded = createUninitializedInternalNonEmpty(m_length, data16);
+            for (unsigned i = 0; i < m_length; ++i)
+                data16[i] = toASCIILower(m_data16[i]);
+            return folded;
+        }
     }
 
-    // Do a faster loop for the case where all the characters are ASCII.
-    UChar* data;
-    RefPtr<StringImpl> newImpl = createUninitialized(m_length, data);
-    UChar ored = 0;
-    for (int32_t i = 0; i < length; ++i) {
-        UChar c = m_data16[i];
-        ored |= c;
-        data[i] = toASCIILower(c);
-    }
-    if (!(ored & ~0x7F))
-        return newImpl.releaseNonNull();
+    if (m_length > static_cast<unsigned>(std::numeric_limits<int32_t>::max()))
+        CRASH();
 
-    // Do a slower implementation for cases that include non-ASCII characters.
+    auto upconvertedCharacters = StringView(*this).upconvertedCharacters();
+
+    UChar* data;
+    auto folded = createUninitializedInternalNonEmpty(m_length, data);
+    int32_t length = m_length;
     UErrorCode status = U_ZERO_ERROR;
-    int32_t realLength = u_strFoldCase(data, length, m_data16, m_length, U_FOLD_CASE_DEFAULT, &status);
+    int32_t realLength = u_strFoldCase(data, length, upconvertedCharacters, length, U_FOLD_CASE_DEFAULT, &status);
     if (U_SUCCESS(status) && realLength == length)
-        return newImpl.releaseNonNull();
-    newImpl = createUninitialized(realLength, data);
+        return folded;
+    ASSERT(realLength > length);
+    folded = createUninitializedInternalNonEmpty(realLength, data);
     status = U_ZERO_ERROR;
-    u_strFoldCase(data, realLength, m_data16, m_length, U_FOLD_CASE_DEFAULT, &status);
+    u_strFoldCase(data, realLength, upconvertedCharacters, length, U_FOLD_CASE_DEFAULT, &status);
     if (U_FAILURE(status))
         return *this;
-    return newImpl.releaseNonNull();
+    return folded;
 }
 
 template<StringImpl::CaseConvertType type, typename CharacterType>
index e6870ba..063ce63 100644 (file)
@@ -681,10 +681,10 @@ public:
 
     WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIILowercase();
     WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIIUppercase();
-    WTF_EXPORT_STRING_API Ref<StringImpl> lower();
-    WTF_EXPORT_STRING_API Ref<StringImpl> upper();
-    WTF_EXPORT_STRING_API Ref<StringImpl> lower(const AtomicString& localeIdentifier);
-    WTF_EXPORT_STRING_API Ref<StringImpl> upper(const AtomicString& localeIdentifier);
+    WTF_EXPORT_STRING_API Ref<StringImpl> convertToLowercaseWithoutLocale();
+    WTF_EXPORT_STRING_API Ref<StringImpl> convertToUppercaseWithoutLocale();
+    WTF_EXPORT_STRING_API Ref<StringImpl> convertToLowercaseWithLocale(const AtomicString& localeIdentifier);
+    WTF_EXPORT_STRING_API Ref<StringImpl> convertToUppercaseWithLocale(const AtomicString& localeIdentifier);
 
     Ref<StringImpl> foldCase();
 
index 1b43056..ce376e2 100644 (file)
@@ -351,32 +351,32 @@ String String::convertToASCIIUppercase() const
     return m_impl->convertToASCIIUppercase();
 }
 
-String String::lower() const
+String String::convertToLowercaseWithoutLocale() const
 {
     if (!m_impl)
         return String();
-    return m_impl->lower();
+    return m_impl->convertToLowercaseWithoutLocale();
 }
 
-String String::upper() const
+String String::convertToUppercaseWithoutLocale() const
 {
     if (!m_impl)
         return String();
-    return m_impl->upper();
+    return m_impl->convertToUppercaseWithoutLocale();
 }
 
-String String::lower(const AtomicString& localeIdentifier) const
+String String::convertToLowercaseWithLocale(const AtomicString& localeIdentifier) const
 {
     if (!m_impl)
         return String();
-    return m_impl->lower(localeIdentifier);
+    return m_impl->convertToLowercaseWithLocale(localeIdentifier);
 }
 
-String String::upper(const AtomicString& localeIdentifier) const
+String String::convertToUppercaseWithLocale(const AtomicString& localeIdentifier) const
 {
     if (!m_impl)
         return String();
-    return m_impl->upper(localeIdentifier);
+    return m_impl->convertToUppercaseWithLocale(localeIdentifier);
 }
 
 String String::stripWhiteSpace() const
index 88c13da..3c55908 100644 (file)
@@ -331,16 +331,12 @@ public:
     String left(unsigned len) const { return substring(0, len); }
     String right(unsigned len) const { return substring(length() - len, len); }
 
-    // Returns a lowercase/uppercase version of the string.
-    // The convertToASCIILowercase is useful in many contexts such as HTML where we don't
-    // want to do any conversion for non-ASCII letters.
     WTF_EXPORT_STRING_API String convertToASCIILowercase() const;
-    WTF_EXPORT_STRING_API String lower() const;
     WTF_EXPORT_STRING_API String convertToASCIIUppercase() const;
-    WTF_EXPORT_STRING_API String upper() const;
-
-    WTF_EXPORT_STRING_API String lower(const AtomicString& localeIdentifier) const;
-    WTF_EXPORT_STRING_API String upper(const AtomicString& localeIdentifier) const;
+    WTF_EXPORT_STRING_API String convertToLowercaseWithoutLocale() const;
+    WTF_EXPORT_STRING_API String convertToUppercaseWithoutLocale() const;
+    WTF_EXPORT_STRING_API String convertToLowercaseWithLocale(const AtomicString& localeIdentifier) const;
+    WTF_EXPORT_STRING_API String convertToUppercaseWithLocale(const AtomicString& localeIdentifier) const;
 
     WTF_EXPORT_STRING_API String stripWhiteSpace() const;
     WTF_EXPORT_STRING_API String stripWhiteSpace(IsWhiteSpaceFunctionPtr) const;
index ab2fd9d..ca852ae 100644 (file)
@@ -1,3 +1,130 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * Modules/mediasource/MediaSource.cpp:
+        (WebCore::MediaSource::isTypeSupported): Use convertToASCIILowercase on MIME type.
+
+        * accessibility/AccessibilityObject.cpp:
+        (WebCore::AccessibilityObject::selectText): Use new names for lower and upper. Also
+        tweaked style a tiny bit and used u_toupper rather than converting an entire
+        string to uppercase.
+
+        * dom/Document.cpp:
+        (WebCore::Document::addImageElementByCaseFoldedUsemap): Renamed to reflect the use
+        of case folding rather than lowercasing.
+        (WebCore::Document::removeImageElementByCaseFoldedUsemap): Ditto.
+        (WebCore::Document::imageElementByCaseFoldedUsemap): Ditto.
+        * dom/Document.h: Ditto.
+        * dom/DocumentOrderedMap.cpp:
+        (WebCore::DocumentOrderedMap::getElementByCaseFoldedMapName): Ditto.
+        (WebCore::DocumentOrderedMap::getElementByCaseFoldedUsemap): Ditto.
+        * dom/DocumentOrderedMap.h: Ditto.
+
+        * dom/TreeScope.cpp:
+        (WebCore::TreeScope::getImageMap): Removed unneeded special case for null string.
+        Simplified logic for cases where the URL does not have a "#" character in it.
+        Use case folding instead of lowercase.
+
+        * editing/cocoa/HTMLConverter.mm:
+        (HTMLConverter::_processText): Removed unneded special case for the empty string.
+        Use makCapitalized instead of Cocoa function for "capitalize". Use upper and lower
+        functions by their new names.
+
+        * html/HTMLImageElement.cpp:
+        (WebCore::HTMLImageElement::parseAttribute): Use case folding instead of
+        lowerasing for the usemap attribute.
+        (WebCore::HTMLImageElement::insertedInto): Ditto.
+        (WebCore::HTMLImageElement::removedFrom): Ditto.
+        (WebCore::HTMLImageElement::matchesCaseFoldedUsemap): Ditto.
+        * html/HTMLImageElement.h: Rename since usemap is case folded now, not lowercased.
+
+        * html/HTMLMapElement.cpp:
+        (WebCore::HTMLMapElement::imageElement): Use case folding instead of lowercasing
+        for usemap.
+        (WebCore::HTMLMapElement::parseAttribute): Ditto.
+
+        * platform/Language.cpp:
+        (WebCore::canonicalLanguageIdentifier): Use convertToASCIILowercase for language code.
+        (WebCore::indexOfBestMatchingLanguageInList): Ditto.
+
+        * platform/graphics/harfbuzz/HarfBuzzShaper.cpp:
+        (WebCore::HarfBuzzShaper::shapeHarfBuzzRuns): Use new name for the upper function.
+
+        * platform/network/HTTPParsers.cpp:
+        (WebCore::parseContentTypeOptionsHeader): Use equalLettersIgnoringASCIICase instead
+        of lowercasing to check for a specific header value.
+
+        * platform/network/MIMEHeader.cpp:
+        (WebCore::retrieveKeyValuePairs): Use convertToASCIILowercase for MIME header name.
+        (WebCore::MIMEHeader::parseContentTransferEncoding): Use equalLettersIgnoringASCIICase
+        instead of lowercasing.
+
+        * platform/network/cf/ResourceHandleCFNet.cpp:
+        (WebCore::allowsAnyHTTPSCertificateHosts): Make this hash ASCII case-insensitive.
+        (WebCore::clientCertificates): Ditto.
+        (WebCore::ResourceHandle::createCFURLConnection): Remove call to lower since the
+        set is now ASCII case-insensitive.
+        (WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Ditto.
+        (WebCore::ResourceHandle::setClientCertificate): Ditto.
+
+        * platform/network/curl/CookieJarCurl.cpp:
+        (WebCore::getNetscapeCookieFormat): Use equalLettersIgnoringASCIICase instead of
+        lowercasing.
+
+        * platform/network/curl/MultipartHandle.cpp:
+        (WebCore::MultipartHandle::didReceiveResponse): Use convertToASCIILowercase to
+        make a MIME type lowercase.
+
+        * platform/network/curl/ResourceHandleCurl.cpp:
+        (WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Removed unneeded
+        conversion to lowercase now that the set is ASCII case-insensitive.
+        (WebCore::ResourceHandle::setClientCertificate): Removed code that populates a map
+        that is then never used for anything.
+
+        * platform/network/curl/ResourceHandleManager.cpp:
+        (WebCore::headerCallback): Use convertToASCIILowercase for MIME type.
+
+        * platform/network/curl/SSLHandle.cpp: Made hash maps keyed by host names
+        ASCII case-insensitive.
+        (WebCore::addAllowedClientCertificate): Removed lowercasing since the map itself
+        is now ASCII case insensitve.
+        (WebCore::setSSLClientCertificate): Ditto. Also use auto for iterator type so we
+        don't have to write out the map type.
+        (WebCore::sslIgnoreHTTPSCertificate): Ditto.
+        (WebCore::certVerifyCallback): Ditto.
+
+        * platform/network/soup/ResourceHandleSoup.cpp: Made hash maps keyed by host names
+        ASCII case-insensitive.
+        (WebCore::allowsAnyHTTPSCertificateHosts): Ditto.
+        (WebCore::handleUnignoredTLSErrors): Ditto.
+        (WebCore::ResourceHandle::setHostAllowsAnyHTTPSCertificate): Ditto.
+        (WebCore::ResourceHandle::setClientCertificate): Ditto.
+
+        * platform/text/LocaleToScriptMappingDefault.cpp: Made hash maps keyed by script
+        names ASCII case-insensitive. USE WTF_ARRAY_LENGTH as appropriate.
+        (WebCore::scriptNameToCode): Use modern style to initialize the map. Removed
+        unnecessary lowercasing of the script name before looking at the map.
+        (WebCore::localeToScriptCodeForFontSelection): Ditto.
+
+        * platform/text/win/LocaleWin.cpp:
+        (WebCore::convertLocaleNameToLCID): Made map ASCII case-insensitive and removed
+        unneeded lowercasing.
+
+        * platform/win/PasteboardWin.cpp:
+        (WebCore::clipboardTypeFromMIMEType): Use equalLettersIgnoringASCIICase instead
+        of lowercasing.
+
+        * rendering/RenderText.cpp:
+        (WebCore::applyTextTransform): Use new names for the upper and lower functions.
+
+        * xml/XMLHttpRequest.cpp:
+        (WebCore::XMLHttpRequest::responseIsXML): Remove unneeded lowercasing, since
+        DOMImplementation now has ASCII case-insensitive handling of MIME types.
+
 2016-02-06  Zalan Bujtas  <zalan@apple.com>
 
         Outline should contribute to visual overflow.
index 3c9105f..c0d14e1 100644 (file)
@@ -733,7 +733,7 @@ bool MediaSource::isTypeSupported(const String& type)
         return false;
 
     // FIXME: Why do we convert to lowercase here, but not in MediaSource::addSourceBuffer?
-    ContentType contentType(type.lower());
+    ContentType contentType(type.convertToASCIILowercase());
     String codecs = contentType.parameter("codecs");
 
     // 2. If type does not contain a valid MIME type string, then return false.
index b07988e..06a432a 100644 (file)
@@ -761,31 +761,28 @@ String AccessibilityObject::selectText(AccessibilitySelectTextCriteria* criteria
         bool replaceSelection = false;
         if (frame->selection().setSelectedRange(closestStringRange.get(), DOWNSTREAM, true)) {
             switch (activity) {
-            case FindAndCapitalize: {
+            case FindAndCapitalize:
                 replacementString = closestString;
                 makeCapitalized(&replacementString, 0);
                 replaceSelection = true;
                 break;
-            }
             case FindAndUppercase:
-                replacementString = closestString.upper();
+                replacementString = closestString.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
                 replaceSelection = true;
                 break;
             case FindAndLowercase:
-                replacementString = closestString.lower();
+                replacementString = closestString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
                 replaceSelection = true;
                 break;
             case FindAndReplaceActivity: {
                 replaceSelection = true;
-                
                 // When applying find and replace activities, we want to match the capitalization of the replaced text,
                 // (unless we're replacing with an abbreviation.)
-                String uppercaseReplacementString = replacementString.upper();
-                if (closestString.length() > 0 && replacementString.length() > 2 && replacementString != uppercaseReplacementString) {
-                    if (closestString[0] == closestString.upper()[0])
+                if (closestString.length() > 0 && replacementString.length() > 2 && replacementString != replacementString.convertToUppercaseWithoutLocale()) {
+                    if (closestString[0] == u_toupper(closestString[0]))
                         makeCapitalized(&replacementString, 0);
                     else
-                        replacementString = replacementString.lower();
+                        replacementString = replacementString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
                 }
                 break;
             }
index f000b1f..37c6ebb 100644 (file)
@@ -766,19 +766,19 @@ void Document::invalidateAccessKeyMap()
     m_elementsByAccessKey.clear();
 }
 
-void Document::addImageElementByLowercasedUsemap(const AtomicStringImpl& name, HTMLImageElement& element)
+void Document::addImageElementByCaseFoldedUsemap(const AtomicStringImpl& name, HTMLImageElement& element)
 {
     return m_imagesByUsemap.add(name, element, *this);
 }
 
-void Document::removeImageElementByLowercasedUsemap(const AtomicStringImpl& name, HTMLImageElement& element)
+void Document::removeImageElementByCaseFoldedUsemap(const AtomicStringImpl& name, HTMLImageElement& element)
 {
     return m_imagesByUsemap.remove(name, element);
 }
 
-HTMLImageElement* Document::imageElementByLowercasedUsemap(const AtomicStringImpl& name) const
+HTMLImageElement* Document::imageElementByCaseFoldedUsemap(const AtomicStringImpl& name) const
 {
-    return m_imagesByUsemap.getElementByLowercasedUsemap(name, *this);
+    return m_imagesByUsemap.getElementByCaseFoldedUsemap(name, *this);
 }
 
 SelectorQuery* Document::selectorQueryForString(const String& selectorString, ExceptionCode& ec)
index cb62fe8..72cbbcc 100644 (file)
@@ -350,9 +350,9 @@ public:
     Element* getElementByAccessKey(const String& key);
     void invalidateAccessKeyMap();
 
-    void addImageElementByLowercasedUsemap(const AtomicStringImpl&, HTMLImageElement&);
-    void removeImageElementByLowercasedUsemap(const AtomicStringImpl&, HTMLImageElement&);
-    HTMLImageElement* imageElementByLowercasedUsemap(const AtomicStringImpl&) const;
+    void addImageElementByCaseFoldedUsemap(const AtomicStringImpl&, HTMLImageElement&);
+    void removeImageElementByCaseFoldedUsemap(const AtomicStringImpl&, HTMLImageElement&);
+    HTMLImageElement* imageElementByCaseFoldedUsemap(const AtomicStringImpl&) const;
 
     SelectorQuery* selectorQueryForString(const String&, ExceptionCode&);
     void clearSelectorQueryCache();
index 3e34b4e..da8e4f2 100644 (file)
@@ -147,18 +147,18 @@ HTMLMapElement* DocumentOrderedMap::getElementByMapName(const AtomicStringImpl&
     }));
 }
 
-HTMLMapElement* DocumentOrderedMap::getElementByLowercasedMapName(const AtomicStringImpl& key, const TreeScope& scope) const
+HTMLMapElement* DocumentOrderedMap::getElementByCaseFoldedMapName(const AtomicStringImpl& key, const TreeScope& scope) const
 {
     return downcast<HTMLMapElement>(get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
-        return is<HTMLMapElement>(element) && downcast<HTMLMapElement>(element).getName().lower().impl() == &key;
+        return is<HTMLMapElement>(element) && equal(downcast<HTMLMapElement>(element).getName().string().foldCase().impl(), &key);
     }));
 }
 
-HTMLImageElement* DocumentOrderedMap::getElementByLowercasedUsemap(const AtomicStringImpl& key, const TreeScope& scope) const
+HTMLImageElement* DocumentOrderedMap::getElementByCaseFoldedUsemap(const AtomicStringImpl& key, const TreeScope& scope) const
 {
     return downcast<HTMLImageElement>(get(key, scope, [] (const AtomicStringImpl& key, const Element& element) {
         // FIXME: HTML5 specification says we should match both image and object elements.
-        return is<HTMLImageElement>(element) && downcast<HTMLImageElement>(element).matchesLowercasedUsemap(key);
+        return is<HTMLImageElement>(element) && downcast<HTMLImageElement>(element).matchesCaseFoldedUsemap(key);
     }));
 }
 
index 720555b..b4988cc 100644 (file)
@@ -60,8 +60,8 @@ public:
     Element* getElementById(const AtomicStringImpl&, const TreeScope&) const;
     Element* getElementByName(const AtomicStringImpl&, const TreeScope&) const;
     HTMLMapElement* getElementByMapName(const AtomicStringImpl&, const TreeScope&) const;
-    HTMLMapElement* getElementByLowercasedMapName(const AtomicStringImpl&, const TreeScope&) const;
-    HTMLImageElement* getElementByLowercasedUsemap(const AtomicStringImpl&, const TreeScope&) const;
+    HTMLMapElement* getElementByCaseFoldedMapName(const AtomicStringImpl&, const TreeScope&) const;
+    HTMLImageElement* getElementByCaseFoldedUsemap(const AtomicStringImpl&, const TreeScope&) const;
     HTMLLabelElement* getElementByLabelForAttribute(const AtomicStringImpl&, const TreeScope&) const;
     Element* getElementByWindowNamedItem(const AtomicStringImpl&, const TreeScope&) const;
     Element* getElementByDocumentNamedItem(const AtomicStringImpl&, const TreeScope&) const;
index d46a3a6..aff6877 100644 (file)
@@ -201,18 +201,16 @@ void TreeScope::removeImageMap(HTMLMapElement& imageMap)
 
 HTMLMapElement* TreeScope::getImageMap(const String& url) const
 {
-    if (url.isNull())
-        return nullptr;
     if (!m_imageMapsByName)
         return nullptr;
-    size_t hashPos = url.find('#');
-    String name = (hashPos == notFound ? String() : url.substring(hashPos + 1)).impl();
+    auto hashPosition = url.find('#');
+    if (hashPosition == notFound)
+        return nullptr;
+    String name = url.substring(hashPosition + 1);
     if (name.isEmpty())
         return nullptr;
-    if (m_rootNode.document().isHTMLDocument()) {
-        AtomicString lowercasedName = name.lower();
-        return m_imageMapsByName->getElementByLowercasedMapName(*lowercasedName.impl(), *this);
-    }
+    if (m_rootNode.document().isHTMLDocument())
+        return m_imageMapsByName->getElementByCaseFoldedMapName(*AtomicString(name.foldCase()).impl(), *this);
     return m_imageMapsByName->getElementByMapName(*AtomicString(name).impl(), *this);
 }
 
index 5f45e63..bc58d90 100644 (file)
@@ -56,6 +56,7 @@
 #import "NSAttributedStringSPI.h"
 #import "RGBColor.h"
 #import "RenderImage.h"
+#import "RenderText.h"
 #import "SoftLinking.h"
 #import "StyleProperties.h"
 #import "StyledElement.h"
@@ -2278,15 +2279,12 @@ void HTMLConverter::_processText(CharacterData& characterData)
 
     if (outputString.length()) {
         String textTransform = _caches->propertyValueForNode(characterData, CSSPropertyTextTransform);
-        if (textTransform.length()) {
-            if (textTransform == "capitalize") {// FIXME: This is extremely inefficient.
-                NSString *temporaryString = outputString;
-                outputString = [temporaryString capitalizedString];
-            } else if (textTransform == "uppercase")
-                outputString = outputString.upper();
-            else if (textTransform == "lowercase")
-                outputString = outputString.lower();
-        }
+        if (textTransform == "capitalize")
+            makeCapitalized(&outputString, 0); // FIXME: Needs to take locale into account to work correctly.
+        else if (textTransform == "uppercase")
+            outputString = outputString.convertToUppercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
+        else if (textTransform == "lowercase")
+            outputString = outputString.convertToLowercaseWithoutLocale(); // FIXME: Needs locale to work correctly.
 
         [_attrStr replaceCharactersInRange:rangeToReplace withString:outputString];
         rangeToReplace.length = outputString.length();
index 8de9563..488c4e6 100644 (file)
@@ -201,20 +201,20 @@ void HTMLImageElement::parseAttribute(const QualifiedName& name, const AtomicStr
     } else if (name == srcAttr || name == srcsetAttr || name == sizesAttr)
         selectImageSource();
     else if (name == usemapAttr) {
-        if (inDocument() && !m_lowercasedUsemap.isNull())
-            document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
+        if (inDocument() && !m_caseFoldedUsemap.isNull())
+            document().removeImageElementByCaseFoldedUsemap(*m_caseFoldedUsemap.impl(), *this);
 
         // The HTMLImageElement's useMap() value includes the '#' symbol at the beginning, which has to be stripped off.
         // FIXME: We should check that the first character is '#'.
-        // FIXME: HTML5 specification says we should strip any leading string before '#'.
-        // FIXME: HTML5 specification says we should ignore usemap attributes without #.
+        // FIXME: HTML specification says we should strip any leading string before '#'.
+        // FIXME: HTML specification says we should ignore usemap attributes without '#'.
         if (value.length() > 1)
-            m_lowercasedUsemap = value.string().substring(1).lower();
+            m_caseFoldedUsemap = value.string().substring(1).foldCase();
         else
-            m_lowercasedUsemap = nullAtom;
+            m_caseFoldedUsemap = nullAtom;
 
-        if (inDocument() && !m_lowercasedUsemap.isNull())
-            document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
+        if (inDocument() && !m_caseFoldedUsemap.isNull())
+            document().addImageElementByCaseFoldedUsemap(*m_caseFoldedUsemap.impl(), *this);
     } else if (name == compositeAttr) {
         // FIXME: images don't support blend modes in their compositing attribute.
         BlendMode blendOp = BlendModeNormal;
@@ -312,8 +312,8 @@ Node::InsertionNotificationRequest HTMLImageElement::insertedInto(ContainerNode&
     // in callbacks back to this node.
     Node::InsertionNotificationRequest insertNotificationRequest = HTMLElement::insertedInto(insertionPoint);
 
-    if (insertionPoint.inDocument() && !m_lowercasedUsemap.isNull())
-        document().addImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
+    if (insertionPoint.inDocument() && !m_caseFoldedUsemap.isNull())
+        document().addImageElementByCaseFoldedUsemap(*m_caseFoldedUsemap.impl(), *this);
 
     if (is<HTMLPictureElement>(parentNode())) {
         setPictureElement(&downcast<HTMLPictureElement>(*parentNode()));
@@ -333,8 +333,8 @@ void HTMLImageElement::removedFrom(ContainerNode& insertionPoint)
     if (m_form)
         m_form->removeImgElement(this);
 
-    if (insertionPoint.inDocument() && !m_lowercasedUsemap.isNull())
-        document().removeImageElementByLowercasedUsemap(*m_lowercasedUsemap.impl(), *this);
+    if (insertionPoint.inDocument() && !m_caseFoldedUsemap.isNull())
+        document().removeImageElementByCaseFoldedUsemap(*m_caseFoldedUsemap.impl(), *this);
     
     if (is<HTMLPictureElement>(parentNode()))
         setPictureElement(nullptr);
@@ -474,10 +474,10 @@ String HTMLImageElement::completeURLsInAttributeValue(const URL& base, const Att
     return HTMLElement::completeURLsInAttributeValue(base, attribute);
 }
 
-bool HTMLImageElement::matchesLowercasedUsemap(const AtomicStringImpl& name) const
+bool HTMLImageElement::matchesCaseFoldedUsemap(const AtomicStringImpl& name) const
 {
-    ASSERT(String(&const_cast<AtomicStringImpl&>(name)).lower().impl() == &name);
-    return m_lowercasedUsemap.impl() == &name;
+    ASSERT(String(&const_cast<AtomicStringImpl&>(name)).foldCase().impl() == &name);
+    return m_caseFoldedUsemap.impl() == &name;
 }
 
 const AtomicString& HTMLImageElement::alt() const
index 447b624..67931b5 100644 (file)
@@ -60,7 +60,7 @@ public:
 
     void setLoadManually(bool loadManually) { m_imageLoader.setLoadManually(loadManually); }
 
-    bool matchesLowercasedUsemap(const AtomicStringImpl&) const;
+    bool matchesCaseFoldedUsemap(const AtomicStringImpl&) const;
 
     const AtomicString& alt() const;
 
@@ -134,7 +134,7 @@ private:
     CompositeOperator m_compositeOperator;
     AtomicString m_bestFitImageURL;
     AtomicString m_currentSrc;
-    AtomicString m_lowercasedUsemap;
+    AtomicString m_caseFoldedUsemap;
     float m_imageDevicePixelRatio;
     bool m_experimentalImageMenuEnabled;
     bool m_hadNameBeforeAttributeChanged { false }; // FIXME: We only need this because parseAttribute() can't see the old value.
index 3ee61ba..ecc8752 100644 (file)
@@ -78,10 +78,8 @@ bool HTMLMapElement::mapMouseEvent(LayoutPoint location, const LayoutSize& size,
 HTMLImageElement* HTMLMapElement::imageElement()
 {
     if (m_name.isEmpty())
-        return 0;
-    AtomicString lowercasedName = m_name.lower();
-    ASSERT(lowercasedName.impl());
-    return document().imageElementByLowercasedUsemap(*lowercasedName.impl());
+        return nullptr;
+    return document().imageElementByCaseFoldedUsemap(*AtomicString(m_name.string().foldCase()).impl());
 }
 
 void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicString& value)
@@ -101,7 +99,7 @@ void HTMLMapElement::parseAttribute(const QualifiedName& name, const AtomicStrin
         String mapName = value;
         if (mapName[0] == '#')
             mapName = mapName.substring(1);
-        m_name = document().isHTMLDocument() ? mapName.lower() : mapName;
+        m_name = document().isHTMLDocument() ? mapName.foldCase() : mapName;
         if (inDocument())
             treeScope().addImageMap(*this);
 
index 65578d0..a8ae8e3 100644 (file)
@@ -99,7 +99,7 @@ Vector<String> userPreferredLanguages()
 
 static String canonicalLanguageIdentifier(const String& languageCode)
 {
-    String lowercaseLanguageCode = languageCode.lower();
+    String lowercaseLanguageCode = languageCode.convertToASCIILowercase();
     
     if (lowercaseLanguageCode.length() >= 3 && lowercaseLanguageCode[2] == '_')
         lowercaseLanguageCode.replace(2, 1, "-");
@@ -109,7 +109,7 @@ static String canonicalLanguageIdentifier(const String& languageCode)
 
 size_t indexOfBestMatchingLanguageInList(const String& language, const Vector<String>& languageList, bool& exactMatch)
 {
-    String lowercaseLanguage = language.lower();
+    String lowercaseLanguage = language.convertToASCIILowercase();
     String languageWithoutLocaleMatch;
     String languageMatchButNotLocale;
     size_t languageWithoutLocaleMatchIndex = 0;
index fde8e06..5b1e72e 100644 (file)
@@ -482,7 +482,7 @@ bool HarfBuzzShaper::shapeHarfBuzzRuns(bool shouldSetDirection)
         hb_buffer_add_utf16(harfBuzzBuffer.get(), &preContext, 1, 1, 0);
 
         if (m_font->isSmallCaps() && u_islower(m_normalizedBuffer[currentRun->startIndex()])) {
-            String upperText = String(m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters()).upper();
+            String upperText = String(m_normalizedBuffer.get() + currentRun->startIndex(), currentRun->numCharacters()).convertToUppercaseWithoutLocale();
             currentFontData = m_font->glyphDataForCharacter(upperText[0], false, SmallCapsVariant).font;
             const UChar* characters = StringView(upperText).upconvertedCharacters();
             hb_buffer_add_utf16(harfBuzzBuffer.get(), reinterpret_cast<const uint16_t*>(characters), currentRun->numCharacters(), 0, currentRun->numCharacters());
index 1d0e9d0..b20cfc3 100644 (file)
@@ -456,7 +456,7 @@ ContentSecurityPolicy::ReflectedXSSDisposition parseXSSProtectionHeader(const St
 #if ENABLE(NOSNIFF)
 ContentTypeOptionsDisposition parseContentTypeOptionsHeader(const String& header)
 {
-    if (header.stripWhiteSpace().lower() == "nosniff")
+    if (equalLettersIgnoringASCIICase(header.stripWhiteSpace(), "nosniff"))
         return ContentTypeOptionsNosniff;
     return ContentTypeOptionsNone;
 }
index 50eefbd..3a598cc 100644 (file)
@@ -70,7 +70,7 @@ static KeyValueMap retrieveKeyValuePairs(WebCore::SharedBufferChunkReader* buffe
             // This is not a key value pair, ignore.
             continue;
         }
-        key = line.substring(0, semiColonIndex).lower().stripWhiteSpace();
+        key = line.substring(0, semiColonIndex).convertToASCIILowercase().stripWhiteSpace();
         value.append(line.substring(semiColonIndex + 1));
     }
     // Store the last property if there is one.
@@ -114,14 +114,14 @@ PassRefPtr<MIMEHeader> MIMEHeader::parseHeader(SharedBufferChunkReader* buffer)
 
 MIMEHeader::Encoding MIMEHeader::parseContentTransferEncoding(const String& text)
 {
-    String encoding = text.stripWhiteSpace().lower();
-    if (encoding == "base64")
+    String encoding = text.stripWhiteSpace();
+    if (equalLettersIgnoringASCIICase(encoding, "base64"))
         return Base64;
-    if (encoding == "quoted-printable")
+    if (equalLettersIgnoringASCIICase(encoding, "quoted-printable"))
         return QuotedPrintable;
-    if (encoding == "7bit")
+    if (equalLettersIgnoringASCIICase(encoding, "7bit"))
         return SevenBit;
-    if (encoding == "binary")
+    if (equalLettersIgnoringASCIICase(encoding, "binary"))
         return Binary;
     LOG_ERROR("Unknown encoding '%s' found in MIME header.", text.ascii().data());
     return Unknown;
index 51390f6..c95a658 100644 (file)
@@ -82,16 +82,15 @@ namespace WebCore {
 
 #if USE(CFNETWORK)
 
-static HashSet<String>& allowsAnyHTTPSCertificateHosts()
+static HashSet<String, ASCIICaseInsensitiveHash>& allowsAnyHTTPSCertificateHosts()
 {
-    static NeverDestroyed<HashSet<String>> hosts;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> hosts;
     return hosts;
 }
 
-static HashMap<String, RetainPtr<CFDataRef>>& clientCerts()
+static HashMap<String, RetainPtr<CFDataRef>, ASCIICaseInsensitiveHash>& clientCertificates()
 {
-    typedef HashMap<String, RetainPtr<CFDataRef>> CertsMap;
-    static NeverDestroyed<CertsMap> certs;
+    static NeverDestroyed<HashMap<String, RetainPtr<CFDataRef>, ASCIICaseInsensitiveHash>> certs;
     return certs;
 }
 
@@ -169,7 +168,7 @@ void ResourceHandle::createCFURLConnection(bool shouldUseCredentialStorage, bool
 #if PLATFORM(IOS)
     sslProps = adoptCF(ResourceHandle::createSSLPropertiesFromNSURLRequest(firstRequest()));
 #else
-    if (allowsAnyHTTPSCertificateHosts().contains(firstRequest().url().host().lower())) {
+    if (allowsAnyHTTPSCertificateHosts().contains(firstRequest().url().host())) {
         sslProps = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
         CFDictionaryAddValue(sslProps.get(), kCFStreamSSLAllowsAnyRoot, kCFBooleanTrue);
         CFDictionaryAddValue(sslProps.get(), kCFStreamSSLAllowsExpiredRoots, kCFBooleanTrue);
@@ -177,8 +176,8 @@ void ResourceHandle::createCFURLConnection(bool shouldUseCredentialStorage, bool
         CFDictionaryAddValue(sslProps.get(), kCFStreamSSLValidatesCertificateChain, kCFBooleanFalse);
     }
 
-    HashMap<String, RetainPtr<CFDataRef>>::iterator clientCert = clientCerts().find(firstRequest().url().host().lower());
-    if (clientCert != clientCerts().end()) {
+    auto clientCert = clientCertificates().find(firstRequest().url().host());
+    if (clientCert != clientCertificates().end()) {
         if (!sslProps)
             sslProps = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
 #if PLATFORM(WIN)
@@ -603,12 +602,12 @@ void ResourceHandle::platformLoadResourceSynchronously(NetworkingContext* contex
 
 void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
 {
-    allowsAnyHTTPSCertificateHosts().add(host.lower());
+    allowsAnyHTTPSCertificateHosts().add(host);
 }
 
-void ResourceHandle::setClientCertificate(const String& host, CFDataRef cert)
+void ResourceHandle::setClientCertificate(const String& host, CFDataRef certificate)
 {
-    clientCerts().set(host.lower(), cert);
+    clientCertificates().set(host, certificate);
 }
 
 void ResourceHandle::platformSetDefersLoading(bool defers)
index b9d6dd4..b276ca7 100644 (file)
@@ -195,20 +195,20 @@ static String getNetscapeCookieFormat(const URL& url, const String& value)
         if (attribute->contains('=')) {
             Vector<String> keyValuePair;
             attribute->split('=', true, keyValuePair);
-            String key = keyValuePair[0].stripWhiteSpace().lower();
+            String key = keyValuePair[0].stripWhiteSpace();
             String val = keyValuePair[1].stripWhiteSpace();
-            if (key == "expires") {
+            if (equalLettersIgnoringASCIICase(key, "expires")) {
                 CString dateStr(reinterpret_cast<const char*>(val.characters8()), val.length());
                 expires = WTF::parseDateFromNullTerminatedCharacters(dateStr.data()) / WTF::msPerSecond;
-            } else if (key == "max-age")
+            } else if (equalLettersIgnoringASCIICase(key, "max-age"))
                 expires = time(0) + val.toInt();
-            else if (key == "domain") 
+            else if (equalLettersIgnoringASCIICase(key, "domain"))
                 domain = val;
-            else if (key == "path") 
+            else if (equalLettersIgnoringASCIICase(key, "path"))
                 path = val;
         } else {
-            String key = attribute->stripWhiteSpace().lower();
-            if (key == "secure")
+            String key = attribute->stripWhiteSpace();
+            if (equalLettersIgnoringASCIICase(key, "secure"))
                 secure = "TRUE";
         }
     }
index 897f95c..9111fa0 100644 (file)
@@ -346,7 +346,7 @@ void MultipartHandle::didReceiveResponse()
         String contentType = m_headers.get(HTTPHeaderName::ContentType);
         String mimeType = extractMIMETypeFromMediaType(contentType);
 
-        response->setMimeType(mimeType.lower());
+        response->setMimeType(mimeType.convertToASCIILowercase());
         response->setTextEncodingName(extractCharsetFromMediaType(contentType));
 
         d->client()->didReceiveResponse(m_resourceHandle, *response);
index 466702a..f7a04e6 100644 (file)
@@ -122,7 +122,7 @@ void ResourceHandle::cancel()
 
 void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
 {
-    allowsAnyHTTPSCertificateHosts(host.lower());
+    allowsAnyHTTPSCertificateHosts(host);
 }
 
 void ResourceHandle::setClientCertificateInfo(const String& host, const String& certificate, const String& key)
@@ -134,18 +134,11 @@ void ResourceHandle::setClientCertificateInfo(const String& host, const String&
 }
 
 #if PLATFORM(WIN) && USE(CF)
-// FIXME:  The CFDataRef will need to be something else when
-// building without 
-static HashMap<String, RetainPtr<CFDataRef> >& clientCerts()
-{
-    static HashMap<String, RetainPtr<CFDataRef> > certs;
-    return certs;
-}
 
-void ResourceHandle::setClientCertificate(const String& host, CFDataRef cert)
+void ResourceHandle::setClientCertificate(const String&, CFDataRef)
 {
-    clientCerts().set(host.lower(), cert);
 }
+
 #endif
 
 void ResourceHandle::platformSetDefersLoading(bool defers)
index 4df0ea6..a63a572 100644 (file)
@@ -497,7 +497,7 @@ static size_t headerCallback(char* ptr, size_t size, size_t nmemb, void* data)
         d->m_response.setURL(URL(ParsedURLString, hdr));
 
         d->m_response.setHTTPStatusCode(httpCode);
-        d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField(HTTPHeaderName::ContentType)).lower());
+        d->m_response.setMimeType(extractMIMETypeFromMediaType(d->m_response.httpHeaderField(HTTPHeaderName::ContentType)).convertToASCIILowercase());
         d->m_response.setTextEncodingName(extractCharsetFromMediaType(d->m_response.httpHeaderField(HTTPHeaderName::ContentType)));
 
         if (d->m_response.isMultipart()) {
index b462f89..d5bd45d 100644 (file)
@@ -39,9 +39,9 @@
 
 namespace WebCore {
 
-typedef std::tuple<WTF::String, WTF::String> clientCertificate;
-static HashMap<String, ListHashSet<String>> allowedHosts;
-static HashMap<String, clientCertificate> allowedClientHosts;
+typedef std::tuple<String, String> clientCertificate;
+static HashMap<String, ListHashSet<String>, ASCIICaseInsensitiveHash> allowedHosts;
+static HashMap<String, clientCertificate, ASCIICaseInsensitiveHash> allowedClientHosts;
 
 void allowsAnyHTTPSCertificateHosts(const String& host)
 {
@@ -52,13 +52,13 @@ void allowsAnyHTTPSCertificateHosts(const String& host)
 void addAllowedClientCertificate(const String& host, const String& certificate, const String& key)
 {
     clientCertificate clientInfo(certificate, key);
-    allowedClientHosts.set(host.lower(), clientInfo);
+    allowedClientHosts.set(host, clientInfo);
 }
 
 void setSSLClientCertificate(ResourceHandle* handle)
 {
     String host = handle->firstRequest().url().host();
-    HashMap<String, clientCertificate>::iterator it = allowedClientHosts.find(host.lower());
+    auto it = allowedClientHosts.find(host);
     if (it == allowedClientHosts.end())
         return;
 
@@ -71,7 +71,7 @@ void setSSLClientCertificate(ResourceHandle* handle)
 
 bool sslIgnoreHTTPSCertificate(const String& host, const ListHashSet<String>& certificates)
 {
-    HashMap<String, ListHashSet<String>>::iterator it = allowedHosts.find(host);
+    auto it = allowedHosts.find(host);
     if (it != allowedHosts.end()) {
         if ((it->value).isEmpty()) {
             it->value = certificates;
@@ -79,8 +79,8 @@ bool sslIgnoreHTTPSCertificate(const String& host, const ListHashSet<String>& ce
         }
         if (certificates.size() != it->value.size())
             return false;
-        ListHashSet<String>::const_iterator certsIter = certificates.begin();
-        ListHashSet<String>::iterator valueIter = (it->value).begin();
+        auto certsIter = certificates.begin();
+        auto valueIter = (it->value).begin();
         for (; valueIter != (it->value).end(); ++valueIter, ++certsIter) {
             if (*certsIter != *valueIter)
                 return false;
@@ -198,13 +198,13 @@ static int certVerifyCallback(int ok, X509_STORE_CTX* ctx)
     d->m_sslErrors = sslCertificateFlag(err);
 
 #if PLATFORM(WIN)
-    HashMap<String, ListHashSet<String>>::iterator it = allowedHosts.find(host);
+    auto it = allowedHosts.find(host);
     ok = (it != allowedHosts.end());
 #else
     ListHashSet<String> certificates;
     if (!pemData(ctx, certificates))
         return 0;
-    ok = sslIgnoreHTTPSCertificate(host.lower(), certificates);
+    ok = sslIgnoreHTTPSCertificate(host, certificates);
 #endif
 
     if (ok) {
index c52c736..bc58cc7 100644 (file)
@@ -244,13 +244,14 @@ static void continueAfterDidReceiveResponse(ResourceHandle*);
 
 static bool gIgnoreSSLErrors = false;
 
-static HashSet<String>& allowsAnyHTTPSCertificateHosts()
+typedef HashSet<String, ASCIICaseInsensitiveHash> HostsSet;
+static HostsSet& allowsAnyHTTPSCertificateHosts()
 {
-    DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<String>, hosts, ());
+    DEPRECATED_DEFINE_STATIC_LOCAL(HostsSet, hosts, ());
     return hosts;
 }
 
-typedef HashMap<String, HostTLSCertificateSet> CertificatesMap;
+typedef HashMap<String, HostTLSCertificateSet, ASCIICaseInsensitiveHash> CertificatesMap;
 static CertificatesMap& clientCertificates()
 {
     DEPRECATED_DEFINE_STATIC_LOCAL(CertificatesMap, certificates, ());
@@ -322,12 +323,12 @@ static bool handleUnignoredTLSErrors(ResourceHandle* handle, SoupMessage* messag
     if (!tlsErrors)
         return false;
 
-    String lowercaseHostURL = handle->firstRequest().url().host().lower();
-    if (allowsAnyHTTPSCertificateHosts().contains(lowercaseHostURL))
+    String host = handle->firstRequest().url().host();
+    if (allowsAnyHTTPSCertificateHosts().contains(host))
         return false;
 
     // We aren't ignoring errors globally, but the user may have already decided to accept this certificate.
-    auto it = clientCertificates().find(lowercaseHostURL);
+    auto it = clientCertificates().find(host);
     if (it != clientCertificates().end() && it->value.contains(certificate))
         return false;
 
@@ -1087,12 +1088,12 @@ bool ResourceHandle::shouldUseCredentialStorage()
 
 void ResourceHandle::setHostAllowsAnyHTTPSCertificate(const String& host)
 {
-    allowsAnyHTTPSCertificateHosts().add(host.lower());
+    allowsAnyHTTPSCertificateHosts().add(host);
 }
 
 void ResourceHandle::setClientCertificate(const String& host, GTlsCertificate* certificate)
 {
-    clientCertificates().add(host.lower(), HostTLSCertificateSet()).iterator->value.add(certificate);
+    clientCertificates().add(host, HostTLSCertificateSet()).iterator->value.add(certificate);
 }
 
 void ResourceHandle::setIgnoreSSLErrors(bool ignoreSSLErrors)
index 5bc360f..553dbce 100644 (file)
@@ -157,20 +157,21 @@ static const ScriptNameCode scriptNameCodeList[] = {
 };
 
 struct ScriptNameCodeMapHashTraits : public HashTraits<String> {
-    static const int minimumTableSize = WTF::HashTableCapacityForSize<sizeof(scriptNameCodeList) / sizeof(ScriptNameCode)>::value;
+    static const int minimumTableSize = WTF::HashTableCapacityForSize<WTF_ARRAY_LENGTH(scriptNameCodeList)>::value;
 };
 
-typedef HashMap<String, UScriptCode, DefaultHash<String>::Hash, ScriptNameCodeMapHashTraits> ScriptNameCodeMap;
+typedef HashMap<String, UScriptCode, ASCIICaseInsensitiveHash, ScriptNameCodeMapHashTraits> ScriptNameCodeMap;
 
 UScriptCode scriptNameToCode(const String& scriptName)
 {
-    static NeverDestroyed<ScriptNameCodeMap> scriptNameCodeMap;
-    if (scriptNameCodeMap.get().isEmpty()) {
-        for (size_t i = 0; i < sizeof(scriptNameCodeList) / sizeof(ScriptNameCode); ++i)
-            scriptNameCodeMap.get().set(ASCIILiteral(scriptNameCodeList[i].name), scriptNameCodeList[i].code);
-    }
+    static NeverDestroyed<ScriptNameCodeMap> scriptNameCodeMap = []() {
+        ScriptNameCodeMap map;
+        for (auto& nameAndCode : scriptNameCodeList)
+            map.add(ASCIILiteral(nameAndCode.name), nameAndCode.code);
+        return map;
+    }();
 
-    ScriptNameCodeMap::iterator it = scriptNameCodeMap.get().find(scriptName.lower());
+    auto it = scriptNameCodeMap.get().find(scriptName);
     if (it != scriptNameCodeMap.get().end())
         return it->value;
     return USCRIPT_INVALID_CODE;
@@ -383,31 +384,33 @@ static const LocaleScript localeScriptList[] = {
 };
 
 struct LocaleScriptMapHashTraits : public HashTraits<String> {
-    static const int minimumTableSize = WTF::HashTableCapacityForSize<sizeof(localeScriptList) / sizeof(LocaleScript)>::value;
+    static const int minimumTableSize = WTF::HashTableCapacityForSize<WTF_ARRAY_LENGTH(localeScriptList)>::value;
 };
 
-typedef HashMap<String, UScriptCode, DefaultHash<String>::Hash, LocaleScriptMapHashTraits> LocaleScriptMap;
+typedef HashMap<String, UScriptCode, ASCIICaseInsensitiveHash, LocaleScriptMapHashTraits> LocaleScriptMap;
 
 UScriptCode localeToScriptCodeForFontSelection(const String& locale)
 {
-    static NeverDestroyed<LocaleScriptMap> localeScriptMap;
-    if (localeScriptMap.get().isEmpty()) {
-        for (size_t i = 0; i < sizeof(localeScriptList) / sizeof(LocaleScript); ++i)
-            localeScriptMap.get().set(ASCIILiteral(localeScriptList[i].locale), localeScriptList[i].script);
-    }
+    static NeverDestroyed<LocaleScriptMap> localeScriptMap = []() {
+        LocaleScriptMap map;
+        for (auto& localeAndScript : localeScriptList)
+            map.add(ASCIILiteral(localeAndScript.locale), localeAndScript.script);
+        return map;
+    }();
 
-    String canonicalLocale = locale.lower().replace('-', '_');
+    String canonicalLocale = locale;
+    canonicalLocale.replace('-', '_');
     while (!canonicalLocale.isEmpty()) {
-        LocaleScriptMap::iterator it = localeScriptMap.get().find(canonicalLocale);
+        auto it = localeScriptMap.get().find(canonicalLocale);
         if (it != localeScriptMap.get().end())
             return it->value;
-        size_t pos = canonicalLocale.reverseFind('_');
-        if (pos == notFound)
+        auto underscorePosition = canonicalLocale.reverseFind('_');
+        if (underscorePosition == notFound)
             break;
-        UScriptCode code = scriptNameToCode(canonicalLocale.substring(pos + 1));
+        UScriptCode code = scriptNameToCode(canonicalLocale.substring(underscorePosition + 1));
         if (code != USCRIPT_INVALID_CODE && code != USCRIPT_UNKNOWN)
             return code;
-        canonicalLocale = canonicalLocale.substring(0, pos);
+        canonicalLocale = canonicalLocale.substring(0, underscorePosition);
     }
     return USCRIPT_COMMON;
 }
index ccd74bc..e67e269 100644 (file)
@@ -48,7 +48,7 @@ using namespace std;
 namespace WebCore {
 
 typedef LCID (WINAPI* LocaleNameToLCIDPtr)(LPCWSTR, DWORD);
-typedef HashMap<String, LCID> NameToLCIDMap;
+typedef HashMap<String, LCID, ASCIICaseInsensitiveHash> NameToLCIDMap;
 
 static String extractLanguageCode(const String& locale)
 {
@@ -107,7 +107,7 @@ static LCID WINAPI convertLocaleNameToLCID(LPCWSTR name, DWORD)
         return LOCALE_USER_DEFAULT;
     DEPRECATED_DEFINE_STATIC_LOCAL(NameToLCIDMap, map, ());
     ensureNameToLCIDMap(map);
-    String localeName = String(name).replace('_', '-').lower();
+    String localeName = String(name).replace('_', '-');
     do {
         NameToLCIDMap::const_iterator iterator = map.find(localeName);
         if (iterator != map.end())
index 3c699cd..031bfd2 100644 (file)
@@ -182,14 +182,14 @@ enum ClipboardDataType { ClipboardDataTypeNone, ClipboardDataTypeURL, ClipboardD
 
 static ClipboardDataType clipboardTypeFromMIMEType(const String& type)
 {
-    String qType = type.stripWhiteSpace().lower();
+    String strippedType = type.stripWhiteSpace();
 
     // two special cases for IE compatibility
-    if (qType == "text" || qType == "text/plain" || qType.startsWith("text/plain;"))
+    if (equalLettersIgnoringASCIICase(strippedType, "text") || equalLettersIgnoringASCIICase(strippedType, "text/plain") || strippedType.startsWith("text/plain;", false))
         return ClipboardDataTypeText;
-    if (qType == "url" || qType == "text/uri-list")
+    if (equalLettersIgnoringASCIICase(strippedType, "url") || equalLettersIgnoringASCIICase(strippedType, "text/uri-list"))
         return ClipboardDataTypeURL;
-    if (qType == "text/html")
+    if (equalLettersIgnoringASCIICase(strippedType, "text/html"))
         return ClipboardDataTypeTextHTML;
 
     return ClipboardDataTypeNone;
index 5731c0b..8c4e829 100644 (file)
@@ -1035,10 +1035,10 @@ void applyTextTransform(const RenderStyle& style, String& text, UChar previousCh
         makeCapitalized(&text, previousCharacter);
         break;
     case UPPERCASE:
-        text = text.upper(style.locale());
+        text = text.convertToUppercaseWithLocale(style.locale());
         break;
     case LOWERCASE:
-        text = text.lower(style.locale());
+        text = text.convertToLowercaseWithLocale(style.locale());
         break;
     }
 }
index f034007..9d817e1 100644 (file)
@@ -1030,9 +1030,7 @@ String XMLHttpRequest::responseMIMEType() const
 
 bool XMLHttpRequest::responseIsXML() const
 {
-    // FIXME: Remove the lower() call when DOMImplementation.isXMLMIMEType() is modified
-    //        to do case insensitive MIME type matching.
-    return DOMImplementation::isXMLMIMEType(responseMIMEType().lower());
+    return DOMImplementation::isXMLMIMEType(responseMIMEType());
 }
 
 int XMLHttpRequest::status() const
index 74df18b..8d7385e 100644 (file)
@@ -1,3 +1,17 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * Plugins/WebBasePluginPackage.mm:
+        (-[WebBasePluginPackage getPluginInfoFromPLists]): Use modern for loops.
+        (-[WebBasePluginPackage supportsExtension:]): Use convertToASCIILowercase for extension assert.
+        Also use modern for loop.
+        (-[WebBasePluginPackage supportsMIMEType:]): Ditto.
+        (-[WebBasePluginPackage MIMETypeForExtension:]): Ditto.
+
 2016-02-03  Jessie Berlin  <jberlin@webkit.org>
 
         Build fix.
index 5bcee27..de796d9 100644 (file)
@@ -216,18 +216,15 @@ static NSString *pathByResolvingSymlinksAndAliases(NSString *thePath)
         MimeClassInfo mimeClassInfo;
         
         NSArray *extensions = [[MIMEDictionary objectForKey:WebPluginExtensionsKey] _web_lowercaseStrings];
-        for (NSUInteger i = 0; i < [extensions count]; ++i) {
+        for (NSString *extension in extensions) {
             // The DivX plug-in lists multiple extensions in a comma separated string instead of using
             // multiple array elements in the property list. Work around this here by splitting the
             // extension string into components.
-            NSArray *extensionComponents = [[extensions objectAtIndex:i] componentsSeparatedByString:@","];
-
-            for (NSString *extension in extensionComponents)
-                mimeClassInfo.extensions.append(extension);
+            for (NSString *component in [extension componentsSeparatedByString:@","])
+                mimeClassInfo.extensions.append(component);
         }
 
-        mimeClassInfo.type = String(MIME).lower();
-
+        mimeClassInfo.type = String(MIME).convertToASCIILowercase();
         mimeClassInfo.desc = [MIMEDictionary objectForKey:WebPluginTypeDescriptionKey];
 
         pluginInfo.mimes.append(mimeClassInfo);
@@ -284,12 +281,10 @@ static NSString *pathByResolvingSymlinksAndAliases(NSString *thePath)
 
 - (BOOL)supportsExtension:(const String&)extension
 {
-    ASSERT(extension.lower() == extension);
+    ASSERT(extension.convertToASCIILowercase() == extension);
     
-    for (size_t i = 0; i < pluginInfo.mimes.size(); ++i) {
-        const Vector<String>& extensions = pluginInfo.mimes[i].extensions;
-
-        if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end())
+    for (auto& entry : pluginInfo.mimes) {
+        if (entry.extensions.contains(extension))
             return YES;
     }
 
@@ -298,26 +293,23 @@ static NSString *pathByResolvingSymlinksAndAliases(NSString *thePath)
 
 - (BOOL)supportsMIMEType:(const WTF::String&)mimeType
 {
-    ASSERT(mimeType.lower() == mimeType);
+    ASSERT(mimeType.convertToASCIILowercase() == mimeType);
     
-    for (size_t i = 0; i < pluginInfo.mimes.size(); ++i) {
-        if (pluginInfo.mimes[i].type == mimeType)
+    for (auto& entry : pluginInfo.mimes) {
+        if (entry.type == mimeType)
             return YES;
     }
-    
+
     return NO;
 }
 
 - (NSString *)MIMETypeForExtension:(const String&)extension
 {
-    ASSERT(extension.lower() == extension);
+    ASSERT(extension.convertToASCIILowercase() == extension);
     
-    for (size_t i = 0; i < pluginInfo.mimes.size(); ++i) {
-        const MimeClassInfo& mimeClassInfo = pluginInfo.mimes[i];
-        const Vector<String>& extensions = mimeClassInfo.extensions;
-
-        if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end())
-            return mimeClassInfo.type;
+    for (auto& entry : pluginInfo.mimes) {
+        if (entry.extensions.contains(extension))
+            return entry.type;
     }
 
     return nil;
index 2ce4a87..6b99ce8 100644 (file)
@@ -1,3 +1,22 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * Plugins/PluginDatabase.cpp:
+        (WebCore::PluginDatabase::pluginForMIMEType): Use ASCII case-insensitive map rather
+        than lowercasing the MIME type.
+        (WebCore::PluginDatabase::setPreferredPluginForMIMEType): Ditto.
+
+        * Plugins/PluginDatabase.h: Make m_preferredPlugins use an ASCII case-insensitive hash.
+
+        * Plugins/PluginPackage.h: Use ASCII case-insensitive hash for maps keyed by MIME type.
+
+        * Plugins/PluginPackageWin.cpp:
+        (WebCore::PluginPackage::fetchInfo): Use convertToASCIILowercase to lowercase a MIME type.
+
 2016-02-04  Joseph Pecoraro  <pecoraro@apple.com>
 
         Web Inspector: InspectorTimelineAgent doesn't need to recompile functions because it now uses the sampling profiler
index 1a0c7e8..169b197 100644 (file)
@@ -104,8 +104,8 @@ bool PluginDatabase::refresh()
         getDeletedPlugins(pluginsToUnload);
 
         // Unload plugins
-        PluginSet::const_iterator end = pluginsToUnload.end();
-        for (PluginSet::const_iterator it = pluginsToUnload.begin(); it != end; ++it)
+        auto end = pluginsToUnload.end();
+        for (auto it = pluginsToUnload.begin(); it != end; ++it)
             remove(it->get());
 
         pluginSetChanged = !pluginsToUnload.isEmpty();
@@ -121,8 +121,8 @@ bool PluginDatabase::refresh()
     // of RealPlayer installed and just removed the newer one, we'll pick up the older one.
     bool shouldSkipUnchangedFiles = !pluginSetChanged;
 
-    HashSet<String>::const_iterator pathsEnd = paths.end();
-    for (HashSet<String>::const_iterator it = paths.begin(); it != pathsEnd; ++it) {
+    auto pathsEnd = paths.end();
+    for (auto it = paths.begin(); it != pathsEnd; ++it) {
         time_t lastModified;
         if (!getFileModificationTime(*it, lastModified))
             continue;
@@ -156,11 +156,11 @@ bool PluginDatabase::refresh()
     m_registeredMIMETypes.clear();
 
     // Register plug-in MIME types
-    PluginSet::const_iterator end = m_plugins.end();
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+    auto end = m_plugins.end();
+    for (auto it = m_plugins.begin(); it != end; ++it) {
         // Get MIME types
-        MIMEToDescriptionsMap::const_iterator map_it = (*it)->mimeToDescriptions().begin();
-        MIMEToDescriptionsMap::const_iterator map_end = (*it)->mimeToDescriptions().end();
+        auto map_it = (*it)->mimeToDescriptions().begin();
+        auto map_end = (*it)->mimeToDescriptions().end();
         for (; map_it != map_end; ++map_it)
             m_registeredMIMETypes.add(map_it->key);
     }
@@ -172,8 +172,8 @@ Vector<PluginPackage*> PluginDatabase::plugins() const
 {
     Vector<PluginPackage*> result;
 
-    PluginSet::const_iterator end = m_plugins.end();
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it)
+    auto end = m_plugins.end();
+    for (auto it = m_plugins.begin(); it != end; ++it)
         result.append((*it).get());
 
     return result;
@@ -190,26 +190,25 @@ int PluginDatabase::preferredPluginCompare(const void* a, const void* b)
 PluginPackage* PluginDatabase::pluginForMIMEType(const String& mimeType)
 {
     if (mimeType.isEmpty())
-        return 0;
+        return nullptr;
 
-    String key = mimeType.lower();
-    PluginSet::const_iterator end = m_plugins.end();
-    PluginPackage* preferredPlugin = m_preferredPlugins.get(key);
+    PluginPackage* preferredPlugin = m_preferredPlugins.get(mimeType);
     if (preferredPlugin
         && preferredPlugin->isEnabled()
-        && preferredPlugin->mimeToDescriptions().contains(key)) {
+        && preferredPlugin->mimeToDescriptions().contains(mimeType)) {
         return preferredPlugin;
     }
 
     Vector<PluginPackage*, 2> pluginChoices;
 
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+    auto end = m_plugins.end();
+    for (auto it = m_plugins.begin(); it != end; ++it) {
         PluginPackage* plugin = (*it).get();
 
         if (!plugin->isEnabled())
             continue;
 
-        if (plugin->mimeToDescriptions().contains(key)) {
+        if (plugin->mimeToDescriptions().contains(mimeType)) {
 #if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
             if (!plugin->ensurePluginLoaded())
                 continue;
@@ -231,18 +230,18 @@ String PluginDatabase::MIMETypeForExtension(const String& extension) const
     if (extension.isEmpty())
         return String();
 
-    PluginSet::const_iterator end = m_plugins.end();
+    auto end = m_plugins.end();
     String mimeType;
     Vector<PluginPackage*, 2> pluginChoices;
     HashMap<PluginPackage*, String> mimeTypeForPlugin;
 
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+    for (auto it = m_plugins.begin(); it != end; ++it) {
         if (!(*it)->isEnabled())
             continue;
 
-        MIMEToExtensionsMap::const_iterator mime_end = (*it)->mimeToExtensions().end();
+        auto mime_end = (*it)->mimeToExtensions().end();
 
-        for (MIMEToExtensionsMap::const_iterator mime_it = (*it)->mimeToExtensions().begin(); mime_it != mime_end; ++mime_it) {
+        for (auto mime_it = (*it)->mimeToExtensions().begin(); mime_it != mime_end; ++mime_it) {
             mimeType = mime_it->key;
             PluginPackage* preferredPlugin = m_preferredPlugins.get(mimeType);
             const Vector<String>& extensions = mime_it->value;
@@ -305,7 +304,7 @@ PluginPackage* PluginDatabase::findPlugin(const URL& url, String& mimeType)
 void PluginDatabase::setPreferredPluginForMIMEType(const String& mimeType, PluginPackage* plugin)
 {
     if (!plugin || plugin->mimeToExtensions().contains(mimeType))
-        m_preferredPlugins.set(mimeType.lower(), plugin);
+        m_preferredPlugins.set(mimeType, plugin);
 }
 
 bool PluginDatabase::fileExistsAndIsNotDisabled(const String& filePath) const
@@ -319,8 +318,8 @@ bool PluginDatabase::fileExistsAndIsNotDisabled(const String& filePath) const
 
 void PluginDatabase::getDeletedPlugins(PluginSet& plugins) const
 {
-    PluginSet::const_iterator end = m_plugins.end();
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+    auto end = m_plugins.end();
+    for (auto it = m_plugins.begin(); it != end; ++it) {
         if (!fileExistsAndIsNotDisabled((*it)->path()))
             plugins.add(*it);
     }
@@ -341,10 +340,10 @@ bool PluginDatabase::add(PassRefPtr<PluginPackage> prpPackage)
 
 void PluginDatabase::remove(PluginPackage* package)
 {
-    MIMEToExtensionsMap::const_iterator it = package->mimeToExtensions().begin();
-    MIMEToExtensionsMap::const_iterator end = package->mimeToExtensions().end();
+    auto it = package->mimeToExtensions().begin();
+    auto end = package->mimeToExtensions().end();
     for ( ; it != end; ++it) {
-        PluginPackageByNameMap::iterator packageInMap = m_preferredPlugins.find(it->key);
+        auto packageInMap = m_preferredPlugins.find(it->key);
         if (packageInMap != m_preferredPlugins.end() && packageInMap->value == package)
             m_preferredPlugins.remove(packageInMap);
     }
@@ -408,11 +407,11 @@ void PluginDatabase::getPluginPathsInDirectories(HashSet<String>& paths) const
 
     String fileNameFilter("");
 
-    Vector<String>::const_iterator dirsEnd = m_pluginDirectories.end();
-    for (Vector<String>::const_iterator dIt = m_pluginDirectories.begin(); dIt != dirsEnd; ++dIt) {
+    auto dirsEnd = m_pluginDirectories.end();
+    for (auto dIt = m_pluginDirectories.begin(); dIt != dirsEnd; ++dIt) {
         Vector<String> pluginPaths = listDirectory(*dIt, fileNameFilter);
-        Vector<String>::const_iterator pluginsEnd = pluginPaths.end();
-        for (Vector<String>::const_iterator pIt = pluginPaths.begin(); pIt != pluginsEnd; ++pIt) {
+        auto pluginsEnd = pluginPaths.end();
+        for (auto pIt = pluginPaths.begin(); pIt != pluginsEnd; ++pIt) {
             if (!fileExistsAndIsNotDisabled(*pIt))
                 continue;
 
@@ -583,8 +582,8 @@ void PluginDatabase::updatePersistentMetadataCache()
         return;
     }
 
-    PluginSet::const_iterator end = m_plugins.end();
-    for (PluginSet::const_iterator it = m_plugins.begin(); it != end; ++it) {
+    auto end = m_plugins.end();
+    for (auto it = m_plugins.begin(); it != end; ++it) {
         if (!(writeUTF8String(file, (*it)->path())
               && writeTime(file, (*it)->lastModified())
               && writeUTF8String(file, (*it)->name())
index bfc48ec..eb6a841 100644 (file)
@@ -107,7 +107,7 @@ namespace WebCore {
         PluginSet m_plugins;
         HashMap<String, RefPtr<PluginPackage> > m_pluginsByPath;
         HashMap<String, time_t> m_pluginPathsWithTimes;
-        HashMap<String, RefPtr<PluginPackage> > m_preferredPlugins;
+        HashMap<String, RefPtr<PluginPackage>, ASCIICaseInsensitiveHash> m_preferredPlugins;
 #if ENABLE(NETSCAPE_PLUGIN_METADATA_CACHE)
         bool m_persistentMetadataCacheIsLoaded;
 #endif
index 2834057..d76eafd 100644 (file)
@@ -39,8 +39,9 @@
 #include <wtf/text/WTFString.h>
 
 namespace WebCore {
-    typedef HashMap<String, String> MIMEToDescriptionsMap;
-    typedef HashMap<String, Vector<String> > MIMEToExtensionsMap;
+
+    typedef HashMap<String, String, ASCIICaseInsensitiveHash> MIMEToDescriptionsMap;
+    typedef HashMap<String, Vector<String>, ASCIICaseInsensitiveHash> MIMEToExtensionsMap;
 
     class PluginPackage : public RefCounted<PluginPackage> {
     public:
index c2bbcc4..7119d88 100644 (file)
@@ -200,7 +200,7 @@ bool PluginPackage::fetchInfo()
     getVersionInfo(versionInfoData.get(), "FileOpenName").split('|', descriptions);
 
     for (unsigned i = 0; i < types.size(); i++) {
-        String type = types[i].lower();
+        String type = types[i].convertToASCIILowercase();
         String description = i < descriptions.size() ? descriptions[i] : "";
         String extensionList = i < extensionLists.size() ? extensionLists[i] : "";
 
@@ -319,8 +319,8 @@ bool PluginPackage::equal(const PluginPackage& a, const PluginPackage& b)
     if (a.m_mimeToExtensions.size() != b.m_mimeToExtensions.size())
         return false;
 
-    MIMEToExtensionsMap::const_iterator::Keys end = a.m_mimeToExtensions.end().keys();
-    for (MIMEToExtensionsMap::const_iterator::Keys it = a.m_mimeToExtensions.begin().keys(); it != end; ++it) {
+    auto end = a.m_mimeToExtensions.end().keys();
+    for (auto it = a.m_mimeToExtensions.begin().keys(); it != end; ++it) {
         if (!b.m_mimeToExtensions.contains(*it))
             return false;
     }
index cab8c28..0406475 100644 (file)
@@ -1,3 +1,60 @@
+2016-02-06  Darin Adler  <darin@apple.com>
+
+        Finish auditing call sites of upper() and lower(), eliminate many, and rename the functions
+        https://bugs.webkit.org/show_bug.cgi?id=153905
+
+        Reviewed by Sam Weinig.
+
+        * NetworkProcess/CustomProtocols/CustomProtocolManager.h: Use ASCII case-insensitive hash
+        for set of registered schemes.
+
+        * Shared/Plugins/Netscape/mac/NetscapePluginModuleMac.mm:
+        (WebKit::getPluginInfoFromPropertyLists): Use convertToASCIILowercase for MIME type and
+        for file extensions.
+
+        * Shared/Plugins/Netscape/x11/NetscapePluginModuleX11.cpp:
+        (WebKit::NetscapePluginModule::parseMIMEDescription): Use convertToASCIILowercase for
+        MIME description.
+
+        * UIProcess/API/efl/ewk_context.cpp:
+        (ewk_context_preferred_languages_set): Use convertToASCIILowercase for language.
+
+        * UIProcess/API/gtk/WebKitWebContext.cpp:
+        (webkit_web_context_set_preferred_languages): Use convertToASCIILowercase for language.
+
+        * UIProcess/Plugins/PluginInfoStore.cpp:
+        (WebKit::PluginInfoStore::findPluginForExtension): Use Vector::contains instead of
+        writing it out using std::find.
+        (WebKit::pathExtension): Lowercase the result with convertToASCIILowercase instead of
+        leaving that to the caller.
+        (WebKit::PluginInfoStore::findPlugin): Removed call to lower since pathExtension
+        handles that now.
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::findPlugin): Use convertToASCIILowercase for MIME type.
+
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::globalURLSchemesWithCustomProtocolHandlers): Use
+        an ASCII case-insensitive hash.
+        (WebKit::WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers):
+        Remove lowercasing, since the hash is now ASCII case-insensitive.
+        (WebKit::WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers):
+        Ditto.
+
+        * UIProcess/WebProcessPool.h: Use an ASCII case-insensitive hash.
+
+        * WebProcess/Plugins/Netscape/NetscapePlugin.cpp:
+        (WebKit::NetscapePlugin::initialize): Use convertToASCIILowercase on parameter names
+        and values.
+
+        * WebProcess/WebCoreSupport/WebFrameLoaderClient.cpp:
+        (WebKit::pluginSupportsExtension): Use convertToASCIILowercase for extension assertion.
+        Also use a modern for loop.
+        (WebKit::WebFrameLoaderClient::objectContentType): Make the checks for empty MIME types
+        a little less redundant. Reordered logic to avoid checking the list of supported MIME
+        types extra times, and to eliminate the need for a boolean. Use convertToASCIILowercase
+        on the extension.
+
 2016-02-06  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         Unreviewed. Fix more incorrect ASSERT introduced in r196053.
index 9cfdc39..bf2bd47 100644 (file)
@@ -36,6 +36,7 @@
 #include <wtf/HashSet.h>
 #include <wtf/RetainPtr.h>
 #include <wtf/Threading.h>
+#include <wtf/text/StringHash.h>
 OBJC_CLASS NSURLSessionConfiguration;
 OBJC_CLASS WKCustomProtocol;
 #else
@@ -99,7 +100,7 @@ private:
     RefPtr<WorkQueue> m_messageQueue;
 
 #if PLATFORM(COCOA)
-    HashSet<String> m_registeredSchemes;
+    HashSet<String, ASCIICaseInsensitiveHash> m_registeredSchemes;
     Lock m_registeredSchemesMutex;
 
     typedef HashMap<uint64_t, RetainPtr<WKCustomProtocol>> CustomProtocolMap;
index 1564136..305f85a 100644 (file)
@@ -186,7 +186,7 @@ static bool getPluginInfoFromPropertyLists(CFBundleRef bundle, PluginModuleInfo&
         if (mimeTypeDescription && CFGetTypeID(mimeTypeDescription) != CFStringGetTypeID())
             mimeTypeDescription = 0;
 
-        mimeClassInfo.type = String(mimeType).lower();
+        mimeClassInfo.type = String(mimeType).convertToASCIILowercase();
         mimeClassInfo.desc = mimeTypeDescription;
 
         // Now get the extensions for this MIME type.
@@ -204,10 +204,10 @@ static bool getPluginInfoFromPropertyLists(CFBundleRef bundle, PluginModuleInfo&
             // multiple array elements in the property list. Work around this here by splitting the
             // extension string into components.
             Vector<String> extensionComponents;
-            String(extension).lower().split(',', extensionComponents);
+            String(extension).convertToASCIILowercase().split(',', extensionComponents);
 
-            for (size_t i = 0; i < extensionComponents.size(); ++i)
-                mimeClassInfo.extensions.append(extensionComponents[i]);
+            for (auto& component : extensionComponents)
+                mimeClassInfo.extensions.append(component);
         }
 
         // Add this MIME type.
index 3627539..acfcf00 100644 (file)
@@ -76,7 +76,7 @@ void NetscapePluginModule::parseMIMEDescription(const String& mimeDescription, V
     ASSERT_ARG(result, result.isEmpty());
 
     Vector<String> types;
-    mimeDescription.lower().split(UChar(';'), false, types);
+    mimeDescription.convertToASCIILowercase().split(UChar(';'), false, types);
     result.reserveInitialCapacity(types.size());
 
     size_t mimeInfoCount = 0;
index 4169776..73a0599 100644 (file)
@@ -563,7 +563,7 @@ void ewk_context_preferred_languages_set(Eina_List* languages)
         Eina_List* l;
         void* data;
         EINA_LIST_FOREACH(languages, l, data)
-            preferredLanguages.append(String::fromUTF8(static_cast<char*>(data)).lower().replace("_", "-"));
+            preferredLanguages.append(String::fromUTF8(static_cast<char*>(data)).convertToASCIILowercase().replace("_", "-"));
     }
 
     WebCore::overrideUserPreferredLanguages(preferredLanguages);
index d6f5e13..af6d872 100644 (file)
@@ -968,7 +968,7 @@ void webkit_web_context_set_preferred_languages(WebKitWebContext* context, const
 
     Vector<String> languages;
     for (size_t i = 0; languageList[i]; ++i)
-        languages.append(String::fromUTF8(languageList[i]).lower().replace("_", "-"));
+        languages.append(String::fromUTF8(languageList[i]).convertToASCIILowercase().replace("_", "-"));
 
     WebCore::overrideUserPreferredLanguages(languages);
     WebCore::languageDidChange();
index 65e3842..8a98c62 100644 (file)
@@ -138,9 +138,7 @@ PluginModuleInfo PluginInfoStore::findPluginForExtension(const String& extension
             continue;
 
         for (const auto& mimeClassInfo : plugin.info.mimes) {
-            const Vector<String>& extensions = mimeClassInfo.extensions;
-            
-            if (std::find(extensions.begin(), extensions.end(), extension) != extensions.end()) {
+            if (mimeClassInfo.extensions.contains(extension)) {
                 // We found a supported extension, set the correct MIME type.
                 mimeType = mimeClassInfo.type;
                 return plugin;
@@ -160,11 +158,11 @@ static inline String pathExtension(const URL& url)
         if (extensionPos != notFound)
             extension = filename.substring(extensionPos + 1);
     }
-    
-    return extension;
+    return extension.convertToASCIILowercase();
 }
 
 #if !PLATFORM(COCOA)
+
 PluginModuleLoadPolicy PluginInfoStore::defaultLoadPolicyForPlugin(const PluginModuleInfo&)
 {
     return PluginModuleLoadNormally;
@@ -190,7 +188,7 @@ PluginModuleInfo PluginInfoStore::findPlugin(String& mimeType, const URL& url, P
     }
 
     // Next, check if any plug-ins claim to support the URL extension.
-    String extension = pathExtension(url).lower();
+    String extension = pathExtension(url);
     if (!extension.isNull() && mimeType.isEmpty()) {
         PluginModuleInfo plugin = findPluginForExtension(extension, mimeType, allowedPluginTypes);
         if (!plugin.path.isNull())
index 7314a38..71651ea 100644 (file)
@@ -1863,7 +1863,7 @@ void WebPageProxy::findPlugin(const String& mimeType, uint32_t processType, cons
 
     MESSAGE_CHECK_URL(urlString);
 
-    newMimeType = mimeType.lower();
+    newMimeType = mimeType.convertToASCIILowercase();
     pluginLoadPolicy = PluginModuleLoadNormally;
 
     PluginData::AllowedPluginTypes allowedPluginTypes = allowOnlyApplicationPlugins ? PluginData::OnlyApplicationPlugins : PluginData::AllPlugins;
index 62b85ec..bf3ce5d 100644 (file)
@@ -913,9 +913,9 @@ void WebProcessPool::registerURLSchemeAsCORSEnabled(const String& urlScheme)
     sendToAllProcesses(Messages::WebProcess::RegisterURLSchemeAsCORSEnabled(urlScheme));
 }
 
-HashSet<String>& WebProcessPool::globalURLSchemesWithCustomProtocolHandlers()
+HashSet<String, ASCIICaseInsensitiveHash>& WebProcessPool::globalURLSchemesWithCustomProtocolHandlers()
 {
-    static NeverDestroyed<HashSet<String>> set;
+    static NeverDestroyed<HashSet<String, ASCIICaseInsensitiveHash>> set;
     return set;
 }
 
@@ -924,10 +924,9 @@ void WebProcessPool::registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const
     if (!urlScheme)
         return;
 
-    String schemeLower = urlScheme.lower();
-    globalURLSchemesWithCustomProtocolHandlers().add(schemeLower);
+    globalURLSchemesWithCustomProtocolHandlers().add(urlScheme);
     for (auto* processPool : allProcessPools())
-        processPool->registerSchemeForCustomProtocol(schemeLower);
+        processPool->registerSchemeForCustomProtocol(urlScheme);
 }
 
 void WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String& urlScheme)
@@ -935,10 +934,9 @@ void WebProcessPool::unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(con
     if (!urlScheme)
         return;
 
-    String schemeLower = urlScheme.lower();
-    globalURLSchemesWithCustomProtocolHandlers().remove(schemeLower);
+    globalURLSchemesWithCustomProtocolHandlers().remove(urlScheme);
     for (auto* processPool : allProcessPools())
-        processPool->unregisterSchemeForCustomProtocol(schemeLower);
+        processPool->unregisterSchemeForCustomProtocol(urlScheme);
 }
 
 #if ENABLE(CACHE_PARTITIONING)
index ff06cf7..b7c75d6 100644 (file)
@@ -317,7 +317,7 @@ public:
     void registerSchemeForCustomProtocol(const String&);
     void unregisterSchemeForCustomProtocol(const String&);
 
-    static HashSet<String>& globalURLSchemesWithCustomProtocolHandlers();
+    static HashSet<String, ASCIICaseInsensitiveHash>& globalURLSchemesWithCustomProtocolHandlers();
     static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
     static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&);
 
index 2483983..b9b296c 100644 (file)
@@ -638,7 +638,7 @@ bool NetscapePlugin::initialize(const Parameters& parameters)
 
 #if PLUGIN_ARCHITECTURE(MAC)
         if (m_pluginModule->pluginQuirks().contains(PluginQuirks::WantsLowercaseParameterNames))
-            parameterName = parameterName.lower();
+            parameterName = parameterName.convertToASCIILowercase();
 #endif
 
         paramNames.append(parameterName.utf8());
@@ -675,7 +675,7 @@ bool NetscapePlugin::initialize(const Parameters& parameters)
     if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) {
         for (size_t i = 0; i < parameters.names.size(); ++i) {
             if (equalLettersIgnoringASCIICase(parameters.names[i], "background")) {
-                setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].lower()));
+                setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].convertToASCIILowercase()));
                 break;
             }
         }
index 98fe998..b89d7a1 100644 (file)
@@ -1508,14 +1508,11 @@ PassRefPtr<Widget> WebFrameLoaderClient::createJavaAppletWidget(const IntSize& p
 
 static bool pluginSupportsExtension(const PluginData& pluginData, const String& extension)
 {
-    ASSERT(extension.lower() == extension);
-
+    ASSERT(extension.convertToASCIILowercase() == extension);
     Vector<MimeClassInfo> mimes;
     Vector<size_t> mimePluginIndices;
     pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices);
-    for (size_t i = 0; i < mimes.size(); ++i) {
-        const MimeClassInfo& mimeClassInfo = mimes[i];
-
+    for (auto& mimeClassInfo : mimes) {
         if (mimeClassInfo.extensions.contains(extension))
             return true;
     }
@@ -1524,42 +1521,37 @@ static bool pluginSupportsExtension(const PluginData& pluginData, const String&
 
 ObjectContentType WebFrameLoaderClient::objectContentType(const URL& url, const String& mimeTypeIn)
 {
-    // FIXME: This should be merged with WebCore::FrameLoader::defaultObjectContentType when the plugin code
-    // is consolidated.
+    // FIXME: This should eventually be merged with WebCore::FrameLoader::defaultObjectContentType.
 
     String mimeType = mimeTypeIn;
     if (mimeType.isEmpty()) {
-        String extension = url.path().substring(url.path().reverseFind('.') + 1).lower();
+        String path = url.path();
+        auto dotPosition = path.reverseFind('.');
+        if (dotPosition == notFound)
+            return ObjectContentFrame;
+        String extension = path.substring(dotPosition + 1).convertToASCIILowercase();
 
         // Try to guess the MIME type from the extension.
         mimeType = MIMETypeRegistry::getMIMETypeForExtension(extension);
-
         if (mimeType.isEmpty()) {
             // Check if there's a plug-in around that can handle the extension.
             if (WebPage* webPage = m_frame->page()) {
                 if (pluginSupportsExtension(webPage->corePage()->pluginData(), extension))
                     return ObjectContentNetscapePlugin;
             }
+            return ObjectContentFrame;
         }
     }
 
-    if (mimeType.isEmpty())
-        return ObjectContentFrame;
-
-    bool plugInSupportsMIMEType = false;
-    if (WebPage* webPage = m_frame->page()) {
-        const PluginData& pluginData = webPage->corePage()->pluginData();
-        if (pluginData.supportsMimeType(mimeType, PluginData::AllPlugins) && webFrame()->coreFrame()->loader().subframeLoader().allowPlugins())
-            plugInSupportsMIMEType = true;
-        else if (pluginData.supportsMimeType(mimeType, PluginData::OnlyApplicationPlugins))
-            plugInSupportsMIMEType = true;
-    }
-    
     if (MIMETypeRegistry::isSupportedImageMIMEType(mimeType))
         return ObjectContentImage;
 
-    if (plugInSupportsMIMEType)
-        return ObjectContentNetscapePlugin;
+    if (WebPage* webPage = m_frame->page()) {
+        auto allowedPluginTypes = webFrame()->coreFrame()->loader().subframeLoader().allowPlugins()
+            ? PluginData::AllPlugins : PluginData::OnlyApplicationPlugins;
+        if (webPage->corePage()->pluginData().supportsMimeType(mimeType, allowedPluginTypes))
+            return ObjectContentNetscapePlugin;
+    }
 
     if (MIMETypeRegistry::isSupportedNonImageMIMEType(mimeType))
         return ObjectContentFrame;