diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog index 7e8949a63e9e..5bae23253471 100644 --- a/LayoutTests/ChangeLog +++ b/LayoutTests/ChangeLog @@ -1,3 +1,20 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding-expected.txt: Added. + * fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding.html: Added. + * fast/dom/HTMLAnchorElement/resources/iframe-with-non-ASCII-matching-anchor.html: Added. + + * fast/media/media-query-non-ASCII-case-folding-expected.txt: Added. + * fast/media/media-query-non-ASCII-case-folding.html: Added. + + * fast/xpath/xpath-non-ASCII-case-folding-expected.txt: Added. + * fast/xpath/xpath-non-ASCII-case-folding.html: Added. + 2016-01-28 Zalan Bujtas Unexpected content wrapping at http://email.osh.com/H/2/v100000152474feb8ec7c1a1f4bbe5c7c0/HTML diff --git a/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding-expected.txt b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding-expected.txt new file mode 100644 index 000000000000..254ac9514c8e --- /dev/null +++ b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding-expected.txt @@ -0,0 +1,3 @@ +This tests whether clicking on an anchor that only matches because of incorrect non-ASCII case folding will scroll to anchor. If clicking on the link below triggers a scroll, the test fails. + +PASS diff --git a/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding.html b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding.html new file mode 100644 index 000000000000..33b91b81fd80 --- /dev/null +++ b/LayoutTests/fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding.html @@ -0,0 +1,2 @@ +

This tests whether clicking on an anchor that only matches because of incorrect non-ASCII case folding will scroll to anchor. If clicking on the link below triggers a scroll, the test fails.

+ diff --git a/LayoutTests/fast/dom/HTMLAnchorElement/resources/iframe-with-non-ASCII-matching-anchor.html b/LayoutTests/fast/dom/HTMLAnchorElement/resources/iframe-with-non-ASCII-matching-anchor.html new file mode 100644 index 000000000000..99a5ca073b93 --- /dev/null +++ b/LayoutTests/fast/dom/HTMLAnchorElement/resources/iframe-with-non-ASCII-matching-anchor.html @@ -0,0 +1,41 @@ + + + + Go to anchor +
+ Anchor + diff --git a/LayoutTests/fast/media/media-query-non-ASCII-case-folding-expected.txt b/LayoutTests/fast/media/media-query-non-ASCII-case-folding-expected.txt new file mode 100644 index 000000000000..6861443bd7dc --- /dev/null +++ b/LayoutTests/fast/media/media-query-non-ASCII-case-folding-expected.txt @@ -0,0 +1,12 @@ +Test media queries to make sure only ASCII case is folded, and other non-ASCII case folding is not performed. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS matchMedia('screen').matches is true +PASS matchMedia('SCREEN').matches is true +PASS matchMedia('ſcreen').matches is false +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/media/media-query-non-ASCII-case-folding.html b/LayoutTests/fast/media/media-query-non-ASCII-case-folding.html new file mode 100644 index 000000000000..a23cbc72a522 --- /dev/null +++ b/LayoutTests/fast/media/media-query-non-ASCII-case-folding.html @@ -0,0 +1,9 @@ + + + + diff --git a/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding-expected.txt b/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding-expected.txt new file mode 100644 index 000000000000..204e618e5ce6 --- /dev/null +++ b/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding-expected.txt @@ -0,0 +1,15 @@ +Test XPath element tag and language matching to make sure only ASCII case is folded, and other non-ASCII case folding is not performed. + +On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE". + + +PASS document.evaluate('count(.//span[attribute::id])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 1 +PASS document.evaluate('count(.//ſpan[attribute::id])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 0 +PASS document.evaluate('count(.//p[lang("en")])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 1 +PASS document.evaluate('count(.//p[lang("sv")])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 1 +PASS document.evaluate('count(.//p[lang("SV")])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 1 +PASS document.evaluate('count(.//p[lang("ſv")])', document.body, null, XPathResult.NUMBER_TYPE, null).numberValue is 0 +PASS successfullyParsed is true + +TEST COMPLETE + diff --git a/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding.html b/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding.html new file mode 100644 index 000000000000..682641c418f0 --- /dev/null +++ b/LayoutTests/fast/xpath/xpath-non-ASCII-case-folding.html @@ -0,0 +1,26 @@ + + + +
+

This paragraph is marked as being in English.

+

This paragraph is marked as being in Swedish.

+

The span element containing the text in this paragraph has an ID specified on it.

+
+ + + diff --git a/Source/WTF/ChangeLog b/Source/WTF/ChangeLog index 9b9c8c20574b..94118df85190 100644 --- a/Source/WTF/ChangeLog +++ b/Source/WTF/ChangeLog @@ -1,3 +1,45 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * wtf/text/AtomicString.h: Removed equalIgnoringCase. + Added some overloads for equalIgnoringASCIICase and moved the function bodies to + bottom of the file to make the function declarations easier to read and scan through. + I plan to do this for more of the functions in this class in the future. + + * wtf/text/StringCommon.h: Added overloads for equalIgnoringASCIICase, + equalPossiblyIgnoringASCIICase, and a helper named equalIgnoringASCIICaseCommon. + Added an overload for equalLettersIgnoringASCIICase. + + * wtf/text/StringImpl.cpp: + (WTF::equalIgnoringCase): Made the few remaining versions of this function private + to this file. Once we get done moving every client that should be using ASCII case + instead to new functions, these will almost certainly be deleted. + (WTF::equalIgnoringASCIICaseNonNull): Tweaked implementation a tiny bit. + + * wtf/text/StringImpl.h: Sorted forward declarations at the top of the file. + Fixed some small formatting mistakes. Removed equalIgnoringCase, but left + equalIgnoringCaseNonNull behind for use by CaseFoldingHash until it is replaced + with ASCIICaseFoldingHash. Improved equalIgnoringASCIICase implementation. + Removed unneeded using for equalIgnoringASCIICase now that StringCommon.h takes + care of it. + + * wtf/text/StringView.cpp: + (WTF::equalIgnoringASCIICase): Deleted. We no longer pass in the length for this, + so the arguments have changed and the implementation is also now in ASCIICommon.h + so it's an inline in the header file. + + * wtf/text/StringView.h: Added an overload of equalIgnoringASCIICase,while + removing another. + + * wtf/text/WTFString.h: Removed some unneeded forward delcarations. Fixed formatting + of the type name NSString *. Improved some comments. Removed equalIgnoringCase. + Separated declaration from implementation in a few cases to start making the + function declarations easier to read and scan through. I plan to do more in the future. + 2016-01-27 Chris Dumez window.atob() should ignore spaces in input diff --git a/Source/WTF/wtf/text/AtomicString.h b/Source/WTF/wtf/text/AtomicString.h index 0edd2b50ebd5..73f26882e63c 100644 --- a/Source/WTF/wtf/text/AtomicString.h +++ b/Source/WTF/wtf/text/AtomicString.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004, 2005, 2006, 2008, 2014 Apple Inc. All rights reserved. + * Copyright (C) 2004-2006, 2008, 2014-2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -215,17 +215,10 @@ inline bool operator!=(const LChar* a, const AtomicString& b) { return !(b == a) inline bool operator!=(const String& a, const AtomicString& b) { return !equal(a.impl(), b.impl()); } inline bool operator!=(const Vector& a, const AtomicString& b) { return !(a == b); } -inline bool equalIgnoringCase(const AtomicString& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const AtomicString& a, const LChar* b) { return equalIgnoringCase(a.impl(), b); } -inline bool equalIgnoringCase(const AtomicString& a, const char* b) { return equalIgnoringCase(a.impl(), reinterpret_cast(b)); } -inline bool equalIgnoringCase(const AtomicString& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const LChar* a, const AtomicString& b) { return equalIgnoringCase(a, b.impl()); } -inline bool equalIgnoringCase(const char* a, const AtomicString& b) { return equalIgnoringCase(reinterpret_cast(a), b.impl()); } -inline bool equalIgnoringCase(const String& a, const AtomicString& b) { return equalIgnoringCase(a.impl(), b.impl()); } - -inline bool equalIgnoringASCIICase(const AtomicString& a, const AtomicString& b) { return equalIgnoringASCIICase(a.impl(), b.impl()); } -inline bool equalIgnoringASCIICase(const AtomicString& a, const String& b) { return equalIgnoringASCIICase(a.impl(), b.impl()); } -inline bool equalIgnoringASCIICase(const String& a, const AtomicString& b) { return equalIgnoringASCIICase(a.impl(), b.impl()); } +bool equalIgnoringASCIICase(const AtomicString&, const AtomicString&); +bool equalIgnoringASCIICase(const AtomicString&, const String&); +bool equalIgnoringASCIICase(const String&, const AtomicString&); +bool equalIgnoringASCIICase(const AtomicString&, const char*); template bool equalLettersIgnoringASCIICase(const AtomicString&, const char (&lowercaseLetters)[length]); @@ -344,6 +337,26 @@ template inline bool equalLettersIgnoringASCIICase(const Atomic return equalLettersIgnoringASCIICase(string.string(), lowercaseLetters); } +inline bool equalIgnoringASCIICase(const AtomicString& a, const AtomicString& b) +{ + return equalIgnoringASCIICase(a.string(), b.string()); +} + +inline bool equalIgnoringASCIICase(const AtomicString& a, const String& b) +{ + return equalIgnoringASCIICase(a.string(), b); +} + +inline bool equalIgnoringASCIICase(const String& a, const AtomicString& b) +{ + return equalIgnoringASCIICase(a, b.string()); +} + +inline bool equalIgnoringASCIICase(const AtomicString& a, const char* b) +{ + return equalIgnoringASCIICase(a.string(), b); +} + } // namespace WTF #ifndef ATOMICSTRING_HIDE_GLOBALS diff --git a/Source/WTF/wtf/text/StringCommon.h b/Source/WTF/wtf/text/StringCommon.h index 09f4e349a988..22529c0d72c9 100644 --- a/Source/WTF/wtf/text/StringCommon.h +++ b/Source/WTF/wtf/text/StringCommon.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Apple Inc. All rights reserved. + * Copyright (C) 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +31,14 @@ namespace WTF { +template bool equalIgnoringASCIICase(const CharacterTypeA*, const CharacterTypeB*, unsigned length); +template bool equalIgnoringASCIICase(const CharacterTypeA*, unsigned lengthA, const CharacterTypeB*, unsigned lengthB); + +template bool equalIgnoringASCIICaseCommon(const StringClassA&, const StringClassB&); + template bool equalLettersIgnoringASCIICase(const CharacterType*, const char* lowercaseLetters, unsigned length); +template bool equalLettersIgnoringASCIICase(const CharacterType*, unsigned charactersLength, const char (&lowercaseLetters)[lowercaseLettersLength]); + template bool equalLettersIgnoringASCIICaseCommon(const StringClass&, const char (&lowercaseLetters)[length]); template @@ -326,6 +333,11 @@ inline bool equalIgnoringASCIICase(const CharacterTypeA* a, const CharacterTypeB return true; } +template inline bool equalIgnoringASCIICase(const CharacterTypeA* a, unsigned lengthA, const CharacterTypeB* b, unsigned lengthB) +{ + return lengthA == lengthB && equalIgnoringASCIICase(a, b, lengthA); +} + template bool equalIgnoringASCIICaseCommon(const StringClassA& a, const StringClassB& b) { @@ -346,6 +358,18 @@ bool equalIgnoringASCIICaseCommon(const StringClassA& a, const StringClassB& b) return equalIgnoringASCIICase(a.characters16(), b.characters16(), length); } +template bool equalIgnoringASCIICaseCommon(const StringClassA& a, const char* b) +{ + unsigned length = a.length(); + if (length != strlen(b)) + return false; + + if (a.is8Bit()) + return equalIgnoringASCIICase(a.characters8(), b, length); + + return equalIgnoringASCIICase(a.characters16(), b, length); +} + template bool startsWith(const StringClassA& reference, const StringClassB& prefix) { @@ -559,6 +583,13 @@ template inline bool equalLettersIgnoringASCIICase(const return true; } +template inline bool equalLettersIgnoringASCIICase(const CharacterType* characters, unsigned charactersLength, const char (&lowercaseLetters)[lowercaseLettersLength]) +{ + ASSERT(strlen(lowercaseLetters) == lowercaseLettersLength - 1); + unsigned lowercaseLettersStringLength = lowercaseLettersLength - 1; + return charactersLength == lowercaseLettersStringLength && equalLettersIgnoringASCIICase(characters, lowercaseLetters, lowercaseLettersStringLength); +} + // This is intentionally not marked inline because it's used often and is not speed-critical enough to want it inlined everywhere. template bool equalLettersIgnoringASCIICaseCommonWithoutLength(const StringClass& string, const char* lowercaseLetters) { @@ -578,12 +609,14 @@ template bool equalLettersIgnoringASCIICaseCommonWithoutLe template inline bool equalLettersIgnoringASCIICaseCommon(const StringClass& string, const char (&lowercaseLetters)[length]) { // Don't actually use the length; we are choosing code size over speed. + ASSERT(strlen(lowercaseLetters) == length - 1); const char* pointer = lowercaseLetters; return equalLettersIgnoringASCIICaseCommonWithoutLength(string, pointer); } } +using WTF::equalIgnoringASCIICase; using WTF::equalLettersIgnoringASCIICase; #endif // StringCommon_h diff --git a/Source/WTF/wtf/text/StringHash.h b/Source/WTF/wtf/text/StringHash.h index 590ff5bd48f6..346c104d431b 100644 --- a/Source/WTF/wtf/text/StringHash.h +++ b/Source/WTF/wtf/text/StringHash.h @@ -110,7 +110,7 @@ namespace WTF { static inline bool equal(const StringImpl* a, const StringImpl* b) { - return equalIgnoringCaseNonNull(a, b); + return equalCompatibiltyCaselessNonNull(a, b); } static unsigned hash(const RefPtr& key) diff --git a/Source/WTF/wtf/text/StringImpl.cpp b/Source/WTF/wtf/text/StringImpl.cpp index d5b7dd664d1f..a676d2b31689 100644 --- a/Source/WTF/wtf/text/StringImpl.cpp +++ b/Source/WTF/wtf/text/StringImpl.cpp @@ -2,7 +2,7 @@ * Copyright (C) 1999 Lars Knoll (knoll@kde.org) * (C) 1999 Antti Koivisto (koivisto@kde.org) * (C) 2001 Dirk Mueller ( mueller@kde.org ) - * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2013-2014 Apple Inc. All rights reserved. + * Copyright (C) 2003-2009, 2013-2016 Apple Inc. All rights reserved. * Copyright (C) 2006 Andrew Wellington (proton@wiretapped.net) * * This library is free software; you can redistribute it and/or @@ -950,7 +950,7 @@ float StringImpl::toFloat(bool* ok) return charactersToFloat(characters16(), m_length, ok); } -bool equalIgnoringCase(const LChar* a, const LChar* b, unsigned length) +static inline bool equalCompatibiltyCaseless(const LChar* a, const LChar* b, unsigned length) { while (length--) { if (StringImpl::latin1CaseFoldTable[*a++] != StringImpl::latin1CaseFoldTable[*b++]) @@ -959,7 +959,7 @@ bool equalIgnoringCase(const LChar* a, const LChar* b, unsigned length) return true; } -bool equalIgnoringCase(const UChar* a, const LChar* b, unsigned length) +static inline bool equalCompatibiltyCaseless(const UChar* a, const LChar* b, unsigned length) { while (length--) { if (u_foldCase(*a++, U_FOLD_CASE_DEFAULT) != StringImpl::latin1CaseFoldTable[*b++]) @@ -968,6 +968,16 @@ bool equalIgnoringCase(const UChar* a, const LChar* b, unsigned length) return true; } +static inline bool equalCompatibiltyCaseless(const LChar* a, const UChar* b, unsigned length) +{ + return equalCompatibiltyCaseless(b, a, length); +} + +static inline bool equalCompatibiltyCaseless(const UChar* a, const UChar* b, unsigned length) +{ + return !u_memcasecmp(a, b, length, U_FOLD_CASE_DEFAULT); +} + size_t StringImpl::find(CharacterMatchFunctionPtr matchFunction, unsigned start) { if (is8Bit()) @@ -1072,7 +1082,7 @@ size_t StringImpl::findIgnoringCase(const LChar* matchString, unsigned index) const LChar* searchCharacters = characters8() + index; unsigned i = 0; - while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { + while (!equalCompatibiltyCaseless(searchCharacters + i, matchString, matchLength)) { if (i == delta) return notFound; ++i; @@ -1083,7 +1093,7 @@ size_t StringImpl::findIgnoringCase(const LChar* matchString, unsigned index) const UChar* searchCharacters = characters16() + index; unsigned i = 0; - while (!equalIgnoringCase(searchCharacters + i, matchString, matchLength)) { + while (!equalCompatibiltyCaseless(searchCharacters + i, matchString, matchLength)) { if (i == delta) return notFound; ++i; @@ -1147,7 +1157,7 @@ ALWAYS_INLINE static size_t findIgnoringCaseInner(const SearchCharacterType* sea unsigned i = 0; // keep looping until we match - while (!equalIgnoringCase(searchCharacters + i, matchCharacters, matchLength)) { + while (!equalCompatibiltyCaseless(searchCharacters + i, matchCharacters, matchLength)) { if (i == delta) return notFound; ++i; @@ -1288,7 +1298,7 @@ ALWAYS_INLINE static size_t reverseFindIgnoringCaseInner(const SearchCharacterTy unsigned delta = std::min(index, length - matchLength); // keep looping until we match - while (!equalIgnoringCase(searchCharacters + delta, matchCharacters, matchLength)) { + while (!equalCompatibiltyCaseless(searchCharacters + delta, matchCharacters, matchLength)) { if (!delta) return notFound; --delta; @@ -1334,8 +1344,8 @@ ALWAYS_INLINE static bool equalInner(const StringImpl* stringImpl, unsigned star return equal(stringImpl->characters16() + startOffset, reinterpret_cast(matchString), matchLength); } if (stringImpl->is8Bit()) - return equalIgnoringCase(stringImpl->characters8() + startOffset, reinterpret_cast(matchString), matchLength); - return equalIgnoringCase(stringImpl->characters16() + startOffset, reinterpret_cast(matchString), matchLength); + return equalCompatibiltyCaseless(stringImpl->characters8() + startOffset, reinterpret_cast(matchString), matchLength); + return equalCompatibiltyCaseless(stringImpl->characters16() + startOffset, reinterpret_cast(matchString), matchLength); } ALWAYS_INLINE static bool equalInner(const StringImpl& stringImpl, unsigned startOffset, const StringImpl& matchString) @@ -1908,73 +1918,10 @@ bool equal(const StringImpl& a, const StringImpl& b) return equalCommon(a, b); } -bool equalIgnoringCase(const StringImpl* a, const StringImpl* b) -{ - if (a == b) - return true; - if (!a || !b) - return false; - - return CaseFoldingHash::equal(a, b); -} - -bool equalIgnoringCase(const StringImpl* a, const LChar* b) -{ - if (!a) - return !b; - if (!b) - return !a; - - unsigned length = a->length(); - - // Do a faster loop for the case where all the characters are ASCII. - UChar ored = 0; - bool equal = true; - if (a->is8Bit()) { - const LChar* as = a->characters8(); - for (unsigned i = 0; i != length; ++i) { - LChar bc = b[i]; - if (!bc) - return false; - UChar ac = as[i]; - ored |= ac; - equal = equal && (toASCIILower(ac) == toASCIILower(bc)); - } - - // Do a slower implementation for cases that include non-ASCII characters. - if (ored & ~0x7F) { - equal = true; - for (unsigned i = 0; i != length; ++i) - equal = equal && u_foldCase(as[i], U_FOLD_CASE_DEFAULT) == u_foldCase(b[i], U_FOLD_CASE_DEFAULT); - } - - return equal && !b[length]; - } - - const UChar* as = a->characters16(); - for (unsigned i = 0; i != length; ++i) { - LChar bc = b[i]; - if (!bc) - return false; - UChar ac = as[i]; - ored |= ac; - equal = equal && (toASCIILower(ac) == toASCIILower(bc)); - } - - // Do a slower implementation for cases that include non-ASCII characters. - if (ored & ~0x7F) { - equal = true; - for (unsigned i = 0; i != length; ++i) { - equal = equal && u_foldCase(as[i], U_FOLD_CASE_DEFAULT) == u_foldCase(b[i], U_FOLD_CASE_DEFAULT); - } - } - - return equal && !b[length]; -} - -bool equalIgnoringCaseNonNull(const StringImpl* a, const StringImpl* b) +bool equalCompatibiltyCaselessNonNull(const StringImpl* a, const StringImpl* b) { - ASSERT(a && b); + ASSERT(a); + ASSERT(b); if (a == b) return true; @@ -1984,15 +1931,15 @@ bool equalIgnoringCaseNonNull(const StringImpl* a, const StringImpl* b) if (a->is8Bit()) { if (b->is8Bit()) - return equalIgnoringCase(a->characters8(), b->characters8(), length); + return equalCompatibiltyCaseless(a->characters8(), b->characters8(), length); - return equalIgnoringCase(b->characters16(), a->characters8(), length); + return equalCompatibiltyCaseless(b->characters16(), a->characters8(), length); } if (b->is8Bit()) - return equalIgnoringCase(a->characters16(), b->characters8(), length); + return equalCompatibiltyCaseless(a->characters16(), b->characters8(), length); - return equalIgnoringCase(a->characters16(), b->characters16(), length); + return equalCompatibiltyCaseless(a->characters16(), b->characters16(), length); } bool equalIgnoringNullity(StringImpl* a, StringImpl* b) @@ -2004,12 +1951,7 @@ bool equalIgnoringNullity(StringImpl* a, StringImpl* b) return equal(a, b); } -bool equalIgnoringASCIICase(const StringImpl& a, const StringImpl& b) -{ - return equalIgnoringASCIICaseCommon(a, b); -} - -bool equalIgnoringASCIICase(const StringImpl* a, const StringImpl*b) +bool equalIgnoringASCIICase(const StringImpl* a, const StringImpl* b) { if (a == b) return true; @@ -2018,22 +1960,11 @@ bool equalIgnoringASCIICase(const StringImpl* a, const StringImpl*b) return equalIgnoringASCIICaseCommon(*a, *b); } -bool equalIgnoringASCIICase(const StringImpl& a, const char* b, unsigned bLength) -{ - if (bLength != a.length()) - return false; - - if (a.is8Bit()) - return equalIgnoringASCIICase(a.characters8(), b, bLength); - - return equalIgnoringASCIICase(a.characters16(), b, bLength); -} - bool equalIgnoringASCIICaseNonNull(const StringImpl* a, const StringImpl* b) { ASSERT(a); ASSERT(b); - return equalIgnoringASCIICaseCommon(*a, *b); + return equalIgnoringASCIICase(*a, *b); } UCharDirection StringImpl::defaultWritingDirection(bool* hasStrongDirectionality) diff --git a/Source/WTF/wtf/text/StringImpl.h b/Source/WTF/wtf/text/StringImpl.h index ca293c6e66af..d44e5cfa5709 100644 --- a/Source/WTF/wtf/text/StringImpl.h +++ b/Source/WTF/wtf/text/StringImpl.h @@ -1,6 +1,6 @@ /* * Copyright (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2005-2010, 2013-2014 Apple Inc. All rights reserved. + * Copyright (C) 2005-2010, 2013-2016 Apple Inc. All rights reserved. * Copyright (C) 2009 Google Inc. All rights reserved. * * This library is free software; you can redistribute it and/or @@ -50,16 +50,20 @@ class LLIntOffsetsExtractor; namespace WTF { +class SymbolImpl; +class SymbolRegistry; + struct CStringTranslator; -template struct HashAndCharactersTranslator; +struct CharBufferFromLiteralDataTranslator; struct HashAndUTF8CharactersTranslator; struct LCharBufferTranslator; -struct CharBufferFromLiteralDataTranslator; +struct StringHash; struct SubstringTranslator; struct UCharBufferTranslator; + template class RetainPtr; -class SymbolImpl; -class SymbolRegistry; + +template struct HashAndCharactersTranslator; enum TextCaseSensitivity { TextCaseSensitive, @@ -751,7 +755,7 @@ class StringImpl { RetainPtr createCFString(); #endif #ifdef __OBJC__ - WTF_EXPORT_STRING_API operator NSString*(); + WTF_EXPORT_STRING_API operator NSString *(); #endif #if STRING_STATS @@ -942,35 +946,18 @@ inline bool equal(const LChar* a, StringImpl* b) { return equal(b, a); } inline bool equal(const char* a, StringImpl* b) { return equal(b, reinterpret_cast(a)); } WTF_EXPORT_STRING_API bool equal(const StringImpl& a, const StringImpl& b); -WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const StringImpl*); -WTF_EXPORT_STRING_API bool equalIgnoringCase(const StringImpl*, const LChar*); -inline bool equalIgnoringCase(const LChar* a, const StringImpl* b) { return equalIgnoringCase(b, a); } -WTF_EXPORT_STRING_API bool equalIgnoringCase(const LChar*, const LChar*, unsigned); -WTF_EXPORT_STRING_API bool equalIgnoringCase(const UChar*, const LChar*, unsigned); -inline bool equalIgnoringCase(const UChar* a, const char* b, unsigned length) { return equalIgnoringCase(a, reinterpret_cast(b), length); } -inline bool equalIgnoringCase(const LChar* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, a, length); } -inline bool equalIgnoringCase(const char* a, const UChar* b, unsigned length) { return equalIgnoringCase(b, reinterpret_cast(a), length); } -inline bool equalIgnoringCase(const char* a, const LChar* b, unsigned length) { return equalIgnoringCase(b, reinterpret_cast(a), length); } -inline bool equalIgnoringCase(const UChar* a, const UChar* b, int length) -{ - ASSERT(length >= 0); - return !u_memcasecmp(a, b, length, U_FOLD_CASE_DEFAULT); -} -WTF_EXPORT_STRING_API bool equalIgnoringCaseNonNull(const StringImpl*, const StringImpl*); +// FIXME: Deprecated. Used only by CaseFoldingHash, which itself is soon to be deprecated and removed, replaced by ASCIICaseFoldingHash. +WTF_EXPORT_STRING_API bool equalCompatibiltyCaselessNonNull(const StringImpl*, const StringImpl*); WTF_EXPORT_STRING_API bool equalIgnoringNullity(StringImpl*, StringImpl*); WTF_EXPORT_STRING_API bool equalIgnoringNullity(const UChar*, size_t length, StringImpl*); -WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl&, const StringImpl&); +bool equalIgnoringASCIICase(const StringImpl&, const StringImpl&); WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl*, const StringImpl*); -WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl& a, const char* b, unsigned bLength); -WTF_EXPORT_STRING_API bool equalIgnoringASCIICaseNonNull(const StringImpl*, const StringImpl*); +WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl&, const char*); +WTF_EXPORT_STRING_API bool equalIgnoringASCIICase(const StringImpl*, const char*); -template -bool equalIgnoringASCIICase(const StringImpl* a, const char (&b)[charactersCount]) -{ - return a ? equalIgnoringASCIICase(*a, b, charactersCount - 1) : false; -} +WTF_EXPORT_STRING_API bool equalIgnoringASCIICaseNonNull(const StringImpl*, const StringImpl*); template bool equalLettersIgnoringASCIICase(const StringImpl&, const char (&lowercaseLetters)[length]); template bool equalLettersIgnoringASCIICase(const StringImpl*, const char (&lowercaseLetters)[length]); @@ -1179,8 +1166,6 @@ inline Ref StringImpl::isolatedCopy() const return create(m_data16, m_length); } -struct StringHash; - // StringHash is the default hash for StringImpl* and RefPtr template struct DefaultHash; template<> struct DefaultHash { @@ -1190,6 +1175,21 @@ template<> struct DefaultHash> { typedef StringHash Hash; }; +inline bool equalIgnoringASCIICase(const StringImpl& a, const StringImpl& b) +{ + return equalIgnoringASCIICaseCommon(a, b); +} + +inline bool equalIgnoringASCIICase(const StringImpl& a, const char* b) +{ + return equalIgnoringASCIICaseCommon(a, b); +} + +inline bool equalIgnoringASCIICase(const StringImpl* a, const char* b) +{ + return a && equalIgnoringASCIICase(*a, b); +} + template inline bool equalLettersIgnoringASCIICase(const StringImpl& string, const char (&lowercaseLetters)[length]) { return equalLettersIgnoringASCIICaseCommon(string, lowercaseLetters); @@ -1204,7 +1204,6 @@ template inline bool equalLettersIgnoringASCIICase(const String using WTF::StringImpl; using WTF::equal; -using WTF::equalIgnoringASCIICase; using WTF::TextCaseSensitivity; using WTF::TextCaseSensitive; using WTF::TextCaseInsensitive; diff --git a/Source/WTF/wtf/text/StringView.cpp b/Source/WTF/wtf/text/StringView.cpp index 997f050d0f76..e206717c0712 100644 --- a/Source/WTF/wtf/text/StringView.cpp +++ b/Source/WTF/wtf/text/StringView.cpp @@ -77,17 +77,6 @@ bool StringView::endsWithIgnoringASCIICase(const StringView& suffix) const return ::WTF::endsWithIgnoringASCIICase(*this, suffix); } -bool equalIgnoringASCIICase(StringView a, const char* b, unsigned bLength) -{ - if (bLength != a.length()) - return false; - - if (a.is8Bit()) - return equalIgnoringASCIICase(a.characters8(), b, bLength); - - return equalIgnoringASCIICase(a.characters16(), b, bLength); -} - CString StringView::utf8(ConversionMode mode) const { if (isNull()) diff --git a/Source/WTF/wtf/text/StringView.h b/Source/WTF/wtf/text/StringView.h index aff4c961a4dd..4ddfe649d2cc 100644 --- a/Source/WTF/wtf/text/StringView.h +++ b/Source/WTF/wtf/text/StringView.h @@ -162,13 +162,9 @@ template void append(Vector -bool equalIgnoringASCIICase(StringView a, const char (&b)[charactersCount]) -{ - return equalIgnoringASCIICase(a, b, charactersCount - 1); -} +bool equalIgnoringASCIICase(StringView, const char*); template bool equalLettersIgnoringASCIICase(StringView, const char (&lowercaseLetters)[length]); @@ -539,6 +535,11 @@ inline bool equalIgnoringASCIICase(StringView a, StringView b) return equalIgnoringASCIICaseCommon(a, b); } +inline bool equalIgnoringASCIICase(StringView a, const char* b) +{ + return equalIgnoringASCIICaseCommon(a, b); +} + class StringView::CodePoints { public: explicit CodePoints(const StringView&); diff --git a/Source/WTF/wtf/text/WTFString.h b/Source/WTF/wtf/text/WTFString.h index 3ca0fbf200d9..88c13daf3390 100644 --- a/Source/WTF/wtf/text/WTFString.h +++ b/Source/WTF/wtf/text/WTFString.h @@ -1,6 +1,6 @@ /* * (C) 1999 Lars Knoll (knoll@kde.org) - * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2012, 2013 Apple Inc. All rights reserved. + * Copyright (C) 2004-2016 Apple Inc. All rights reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -34,9 +34,6 @@ namespace WTF { -class CString; -struct StringHash; - // Declarations of string operations WTF_EXPORT_STRING_API int charactersToIntStrict(const LChar*, size_t, bool* ok = 0, int base = 10); @@ -406,7 +403,7 @@ class String { WTF_EXPORT_STRING_API bool isSafeToSendToAnotherThread() const; // Prevent Strings from being implicitly convertable to bool as it will be ambiguous on any platform that - // allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString*). + // allows implicit conversion to another pointer type (e.g., Mac allows implicit conversion to NSString *). typedef struct ImplicitConversionFromWTFStringToBoolDisallowedA* (String::*UnspecifiedBoolTypeA); typedef struct ImplicitConversionFromWTFStringToBoolDisallowedB* (String::*UnspecifiedBoolTypeB); operator UnspecifiedBoolTypeA() const; @@ -418,11 +415,12 @@ class String { #endif #ifdef __OBJC__ - WTF_EXPORT_STRING_API String(NSString*); + WTF_EXPORT_STRING_API String(NSString *); - // This conversion maps NULL to "", which loses the meaning of NULL, but we - // need this mapping because AppKit crashes when passed nil NSStrings. - operator NSString*() const { if (!m_impl) return @""; return *m_impl; } + // This conversion converts the null string to an empty NSString rather than to nil. + // Given Cocoa idioms, this is a more useful default. Clients that need to preserve the + // null string can check isNull explicitly. + operator NSString *() const; #endif WTF_EXPORT_STRING_API static String make8BitFrom16BitSource(const UChar*, size_t); @@ -505,16 +503,8 @@ inline bool operator!=(const char* a, const String& b) { return !equal(reinterpr template inline bool operator!=(const Vector& a, const String& b) { return !(a == b); } template inline bool operator!=(const String& a, const Vector& b) { return b != a; } -inline bool equalIgnoringCase(const String& a, const String& b) { return equalIgnoringCase(a.impl(), b.impl()); } -inline bool equalIgnoringCase(const String& a, const LChar* b) { return equalIgnoringCase(a.impl(), b); } -inline bool equalIgnoringCase(const String& a, const char* b) { return equalIgnoringCase(a.impl(), reinterpret_cast(b)); } -inline bool equalIgnoringCase(const LChar* a, const String& b) { return equalIgnoringCase(a, b.impl()); } -inline bool equalIgnoringCase(const char* a, const String& b) { return equalIgnoringCase(reinterpret_cast(a), b.impl()); } - -bool equalPossiblyIgnoringCase(const String&, const String&, bool ignoreCase); - -inline bool equalIgnoringASCIICase(const String& a, const String& b) { return equalIgnoringASCIICase(a.impl(), b.impl()); } -template inline bool equalIgnoringASCIICase(const String& a, const char (&b)[charactersCount]) { return equalIgnoringASCIICase(a.impl(), b); } +bool equalIgnoringASCIICase(const String&, const String&); +bool equalIgnoringASCIICase(const String&, const char*); template bool equalLettersIgnoringASCIICase(const String&, const char (&lowercaseLetters)[length]); @@ -525,6 +515,13 @@ inline bool operator!(const String& str) { return str.isNull(); } inline void swap(String& a, String& b) { a.swap(b); } +#ifdef __OBJC__ + +// Used in a small number of places where the long standing behavior has been "nil if empty". +NSString * nsStringNilIfEmpty(const String&); + +#endif + // Definitions of string operations inline String::String(StringImpl& impl) @@ -597,12 +594,22 @@ inline bool String::containsOnlyLatin1() const return !(ored & 0xFF00); } - #ifdef __OBJC__ -// This is for situations in WebKit where the long standing behavior has been -// "nil if empty", so we try to maintain longstanding behavior for the sake of -// entrenched clients -inline NSString* nsStringNilIfEmpty(const String& str) { return str.isEmpty() ? nil : (NSString*)str; } + +inline String::operator NSString *() const +{ + if (!m_impl) + return @""; + return *m_impl; +} + +inline NSString * nsStringNilIfEmpty(const String& string) +{ + if (string.isEmpty()) + return nil; + return *string.impl(); +} + #endif inline bool String::containsOnlyASCII() const @@ -669,11 +676,6 @@ inline bool String::isAllSpecialCharacters() const return WTF::isAllSpecialCharacters(characters16(), len); } -inline bool equalPossiblyIgnoringCase(const String& a, const String& b, bool ignoreCase) -{ - return ignoreCase ? equalIgnoringCase(a, b) : (a == b); -} - // StringHash is the default hash for String template struct DefaultHash; template<> struct DefaultHash { @@ -718,6 +720,16 @@ template inline bool equalLettersIgnoringASCIICase(const String return equalLettersIgnoringASCIICase(string.impl(), lowercaseLetters); } +inline bool equalIgnoringASCIICase(const String& a, const String& b) +{ + return equalIgnoringASCIICase(a.impl(), b.impl()); +} + +inline bool equalIgnoringASCIICase(const String& a, const char* b) +{ + return equalIgnoringASCIICase(a.impl(), b); +} + } using WTF::CString; @@ -739,8 +751,6 @@ using WTF::charactersToIntPtr; using WTF::charactersToDouble; using WTF::charactersToFloat; using WTF::equal; -using WTF::equalIgnoringCase; -using WTF::equalLettersIgnoringASCIICase; using WTF::find; using WTF::isAllSpecialCharacters; using WTF::isSpaceOrNewline; @@ -749,4 +759,5 @@ using WTF::ASCIILiteral; using WTF::StringCapture; #include + #endif diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog index 806fddf80730..7c218a4294e0 100644 --- a/Source/WebCore/ChangeLog +++ b/Source/WebCore/ChangeLog @@ -1,3 +1,247 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + Tests: fast/media/media-query-non-ASCII-case-folding.html + fast/dom/HTMLAnchorElement/anchor-non-ASCII-case-folding.html + fast/xpath/xpath-non-ASCII-case-folding.html + + No tests included that cover the minor behavior changes in Document::setDomain, + CSPSource::schemeMatches, CSPSource::hostMatches, OriginAccessEntry::operator==, + UserContentURLPattern::matches, UserContentURLPattern::matchesHost, + ContentFilterUnblockHandler::canHandleRequest. Would like to add tests for those + if possible, but it seems clear all are progressions. + + For background on why this is the right thing to do in almost every case: + + - MIME types are all ASCII and not case sensitive (details in RFC 2045) + + - case insensitive comparisons in HTML are all "ASCII case-insensitive" + https://www.w3.org/TR/html/infrastructure.html#ascii-case-insensitive + - same for CSS + + * Modules/webdatabase/DatabaseAuthorizer.cpp: + (WebCore::DatabaseAuthorizer::denyBasedOnTableName): Use equalIgnoringASCIICase. + No change in behavior since the string we are comparing with is always + "__WebKitDatabaseInfoTable__" in practice. + + * accessibility/AccessibilityNodeObject.cpp: + (WebCore::siblingWithAriaRole): Changed argument type to take a const char*, + added some FIXMEs and use equalIgnoringCase. No change in behavior since the + strings we are comparing with are "menu" and "menuitem". + (WebCore::AccessibilityNodeObject::menuElementForMenuButton): Updated to pass + arguments in reverse order. + (WebCore::AccessibilityNodeObject::menuItemElementForMenu): Ditto. + + * css/CSSParser.cpp: + (WebCore::CSSParser::parseFontFaceValue): Use equalIgnoringASCIICase. + No change in behavior because the property names are all ASCII constants. + + * css/CSSParserValues.h: Removed unused equalIgnoringCase function. + + * css/MediaQueryEvaluator.cpp: + (WebCore::MediaQueryEvaluator::mediaTypeMatch): Use equalIgnoringASCIICase. + Changes behavior: No non-ASCII case folding when matching media types. + Covered by new test. + (WebCore::MediaQueryEvaluator::mediaTypeMatchSpecific): Use equalIgnoringASCIICase. + No change in behavior since the only string this is ever called with is "print". + + * dom/DataTransfer.cpp: + (WebCore::DataTransfer::hasFileOfType): Use equalIgnoringASCIICase. + No change in behavior because local files will not have content types with + non-ASCII characters in them. In the extremely unlikely case that this is incorrect, + the change in behavior is a progression. + + * dom/Document.cpp: + (WebCore::Document::setDomain): Use equalIgnoringASCIICase. + Changes behavior: Domains considered equal because of non-ASCII case folding + would get through without an error before, and now will properly throw an exception. + + * dom/Element.cpp: + (WebCore::isStyleAttribute): Refactored into a helper function. Use + equalLettersIgnoringASCIICase. No change in behavior. + (WebCore::Element::synchronizeAttribute): Use isStyleAttribute. + + * dom/TreeScope.cpp: + (WebCore::TreeScope::findAnchor): Use equalIgnoringASCIICase. + Changes behavior: Could go to an anchor and it would be considered a match because + of non-ASCII case folding. Covered by new test. + + * html/HiddenInputType.cpp: + (WebCore::HiddenInputType::appendFormData): Use equalIgnoringASCIICase. + No change in behavior: comparing with an ASCII literal. + * html/canvas/WebGL2RenderingContext.cpp: + (WebCore::WebGL2RenderingContext::getExtension): Ditto. + * html/canvas/WebGLRenderingContext.cpp: + (WebCore::WebGLRenderingContext::getExtension): Ditto. + + * html/parser/CSSPreloadScanner.cpp: + (WebCore::CSSPreloadScanner::emitRule): Use equalLettersIgnoringASCIICase and + StringView to avoid needing a special ruleEqualIgnoringCase function. + No change in behavior. + + * inspector/InspectorNodeFinder.cpp: + (WebCore::InspectorNodeFinder::matchesElement): Use equalIgnoringASCIICase. + Changes behavior, but it's an inspector UI thing, not a web behavior thing, + so I don't think a new regression test is needed. + + * loader/HistoryController.cpp: + (WebCore::HistoryController::currentItemShouldBeReplaced): Use + equalIgnoringASCIICase. No change in behavior because we are comparing + with "about:blank". + + * loader/SubframeLoader.cpp: + (WebCore::findPluginMIMETypeFromURL): Use equalIgnoringASCIICase. + No change in behavior unless a plug-in claims an extension with non-ASCII + characters. I don't think a new regression test is needed. + + * loader/appcache/ApplicationCacheHost.cpp: + (WebCore::ApplicationCacheHost::shouldLoadResourceFromApplicationCache): + Use equalIgnoringASCIICase. No change in behavior because both strings are + protocols from URLs and we don't parse non-ASCII characters into protocol strings; + non-ASCII are already encoding as punycode. + * loader/appcache/ManifestParser.cpp: + (WebCore::parseManifest): Ditto. + + * page/ContentSecurityPolicy.cpp: + (WebCore::isExperimentalDirectiveName): Added. Used by isDirectiveName. + Uses equalLettersIgnoringASCIICase. No change in behavior. + (WebCore::isDirectiveName): Use equalLettersIgnoringASCIICase. + No change in behavior. + (WebCore::isSourceListNone): Use equalLettersIgnoringASCIICase. No + change in behavior. + (WebCore::CSPSource::schemeMatches): Use equalLettersIgnoringASCIICase + and equalIgnoringASCIICase. It's all about comparing URL protocols. The + old code might have done something strange if someone specified a protocol + with a non-ASCII character in it. + (WebCore::CSPSource::hostMatches): Use equalIgnoringASCIICase. + (WebCore::CSPSourceList::parseSource): Use equalLettersIgnoringASCIICase. + No change in behavior. + (WebCore::CSPDirectiveList::checkSourceAndReportViolation): Tweaked code + to do less unnecessary String allocation. + (WebCore::CSPDirectiveList::parseReflectedXSS): Use + equalLettersIgnoringASCIICase. No change in behavior. + (WebCore::CSPDirectiveList::addDirective): Ditto. + (WebCore::ContentSecurityPolicy::reportUnsupportedDirective): Use + equalLettersIgnoringASCIICase and remove unneeded global constant strings. + No change in behavior. + (WebCore::ContentSecurityPolicy::reportDirectiveAsSourceExpression): + Tweak code to eliminate unneeded local. + (WebCore::ContentSecurityPolicy::reportDuplicateDirective): Ditto. + (WebCore::ContentSecurityPolicy::reportInvalidSourceExpression): Use + equalLettersIgnoringASCIICase. No change in behavior. + + * page/OriginAccessEntry.h: + (WebCore::operator==): Use equalLettersIgnoringASCIICase. + + * page/Performance.cpp: + (WebCore::Performance::webkitGetEntriesByName): Use equalLettersIgnoringASCIICase. + No change in behavior. + + * page/UserContentURLPattern.cpp: + (WebCore::UserContentURLPattern::matches): Use equalIgnoringASCIICase to match + schemes. + (WebCore::UserContentURLPattern::matchesHost): Use equalIgnoringASCIICase to + match host names. + + * platform/URL.cpp: + (WebCore::URL::init): Use equalIgnoringASCIICase, and also use StringView to + avoid having to allocate a second string just for comparison purposes. Should be + better for efficiency with no change in behavior. + + * platform/cocoa/ContentFilterUnblockHandlerCocoa.mm: + (WebCore::ContentFilterUnblockHandler::canHandleRequest): Use equalIgnoringASCIICase + to compare hosts. + + * platform/efl/PlatformSpeechSynthesisProviderEfl.cpp: + (WebCore::PlatformSpeechSynthesisProviderEfl::voiceName): Use StringView and + equalIgnoringASCIICase to compare language tags. No test needed because there are + no language tags with non-ASCII characters in them. + + * platform/graphics/FontCache.cpp: + (WebCore::FontPlatformDataCacheKey::operator==): Changed to use the equal + function from CaseFoldingHash. In a subsequent patch we will change this to be + ASCIICaseFoldingHash since font names don't need to compare non-ASCII characters + in a case folding manner, but for now preserve behavior. + (WebCore::alternateFamilyName): Use equalLettersIgnoringASCIICase to avoid having + to use a special familyNameEqualIgnoringCase function. This does mean there will + be a null check and a length check that wasn't there before, but the actual + comparison function will be tighter. Guessing it will be a wash. Also improved + the comments and sorted the Windows cases in with the others. No behavior change. + + * platform/graphics/FontCascade.cpp: + (WebCore::operator==): Changed to use the equal function from CaseFoldingHash. + Same rationale as above in FontPlatformDataCacheKey. + + * platform/graphics/FontDescription.cpp: + (WebCore::FontCascadeDescription::familiesEqualForTextAutoSizing): Use + equalIgnoringASCIICase to compare font family names. Only possible change in + behavior would be if actual fonts with non-ASCII names but that were specified + with different case in style sheets. Highly unlikely this exists. + + * platform/graphics/MediaPlayer.cpp: + (WebCore::MediaPlayer::supportsType): Use equalLettersIgnoringASCIICase. + No change in behavior. + * platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp: + (WebCore::keySystemIsSupported): Ditto. + + * platform/graphics/freetype/FontCacheFreeType.cpp: + (WebCore::isCommonlyUsedGenericFamily): Added. + (WebCore::FontCache::createFontPlatformData): Moved code into the + isCommonlyUsedGenericFamily helper and used equalIgnoringASCIICase. + + * platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp: + (WebCore::FontCustomPlatformData::supportsFormat): Use + equalLettersIgnoringASCIICase. No change in behavior. + * platform/graphics/win/FontCacheWin.cpp: + (WebCore::adjustedGDIFontWeight): Ditto. + (WebCore::FontCache::createFontPlatformData): Ditto. + * platform/graphics/win/FontCustomPlatformData.cpp: + (WebCore::FontCustomPlatformData::supportsFormat): Ditto. + * platform/graphics/win/FontCustomPlatformDataCairo.cpp: + (WebCore::FontCustomPlatformData::supportsFormat): Ditto. + + * platform/mac/PlatformSpeechSynthesizerMac.mm: + (-[WebSpeechSynthesisWrapper speakUtterance:]): Use equalIgnoringASCIICase to + compare languages. No change in behavior because languages have all-ASCII names. + + * platform/network/CacheValidation.cpp: + (WebCore::shouldUpdateHeaderAfterRevalidation): Use equalIgnoringASCIICase. + No change in behavior since it's a fixed list of all ASCII headers. + * platform/network/curl/ResourceHandleManager.cpp: + (WebCore::isAppendableHeader): Ditto. + + * platform/network/mac/ResourceHandleMac.mm: + (WebCore::ResourceHandle::willSendRequest): Use equalIgnoringASCIICase. + No change in behavior because HTTP methods are all ASCII letters. + + * platform/text/mac/LocaleMac.mm: + (WebCore::determineLocale): Use equalIgnoringASCIICase. No change in behavior + because locale languages identifiers are all ASCII. + * platform/text/win/LocaleWin.cpp: + (WebCore::LCIDFromLocaleInternal): Ditto. + + * svg/SVGToOTFFontConversion.cpp: + (WebCore::SVGToOTFFontConverter::appendArabicReplacementSubtable): + Use equalIgnoringASCIICase. No change in behavior because Arabic form attribute + values are all ASCII. + + * xml/XMLHttpRequest.cpp: + (WebCore::XMLHttpRequest::uppercaseKnownHTTPMethod): Use equalIgnoringASCIICase. + No change in behavior because these are all fixed known ASCII HTTP method names. + + * xml/XPathFunctions.cpp: + (WebCore::XPath::FunLang::evaluate): Use equalIgnoringASCIICase. Changes behavior + if specifying a non-ASCII character. Covered by new test. + + * xml/XPathStep.cpp: + (WebCore::XPath::nodeMatchesBasicTest): Use equalIgnoringASCIICase. Changes + behavior if an element local name or XPath predicate has a non-ASCII character. + Covered by new test. + 2016-01-28 Zalan Bujtas Unexpected content wrapping at http://email.osh.com/H/2/v100000152474feb8ec7c1a1f4bbe5c7c0/HTML diff --git a/Source/WebCore/Modules/webdatabase/DatabaseAuthorizer.cpp b/Source/WebCore/Modules/webdatabase/DatabaseAuthorizer.cpp index 3ed2eb658aa7..0933f206ccdd 100644 --- a/Source/WebCore/Modules/webdatabase/DatabaseAuthorizer.cpp +++ b/Source/WebCore/Modules/webdatabase/DatabaseAuthorizer.cpp @@ -407,12 +407,14 @@ int DatabaseAuthorizer::denyBasedOnTableName(const String& tableName) const return SQLAuthAllow; // Sadly, normal creates and drops end up affecting sqlite_master in an authorizer callback, so - // it will be tough to enforce all of the following policies - //if (equalIgnoringCase(tableName, "sqlite_master") || equalIgnoringCase(tableName, "sqlite_temp_master") || - // equalIgnoringCase(tableName, "sqlite_sequence") || equalIgnoringCase(tableName, Database::databaseInfoTableName())) - // return SQLAuthDeny; - - if (equalIgnoringCase(tableName, m_databaseInfoTableName)) + // it will be tough to enforce all of the following policies. + // if (equalIgnoringASCIICase(tableName, "sqlite_master") + // || equalIgnoringASCIICase(tableName, "sqlite_temp_master") + // || equalIgnoringASCIICase(tableName, "sqlite_sequence") + // || equalIgnoringASCIICase(tableName, Database::databaseInfoTableName())) + // return SQLAuthDeny; + + if (equalIgnoringASCIICase(tableName, m_databaseInfoTableName)) return SQLAuthDeny; return SQLAuthAllow; diff --git a/Source/WebCore/accessibility/AccessibilityNodeObject.cpp b/Source/WebCore/accessibility/AccessibilityNodeObject.cpp index ea8e20b9ddad..a00df3dca2b3 100644 --- a/Source/WebCore/accessibility/AccessibilityNodeObject.cpp +++ b/Source/WebCore/accessibility/AccessibilityNodeObject.cpp @@ -1193,15 +1193,16 @@ String AccessibilityNodeObject::ariaAccessibilityDescription() const return String(); } -static Element* siblingWithAriaRole(String role, Node* node) +static Element* siblingWithAriaRole(Node* node, const char* role) { + // FIXME: Either we should add a null check here or change the function to take a reference instead of a pointer. ContainerNode* parent = node->parentNode(); if (!parent) return nullptr; for (auto& sibling : childrenOfType(*parent)) { - const AtomicString& siblingAriaRole = sibling.fastGetAttribute(roleAttr); - if (equalIgnoringCase(siblingAriaRole, role)) + // FIXME: Should skip sibling that is the same as the node. + if (equalIgnoringASCIICase(sibling.fastGetAttribute(roleAttr), role)) return &sibling; } @@ -1213,7 +1214,7 @@ Element* AccessibilityNodeObject::menuElementForMenuButton() const if (ariaRoleAttribute() != MenuButtonRole) return nullptr; - return siblingWithAriaRole("menu", node()); + return siblingWithAriaRole(node(), "menu"); } AccessibilityObject* AccessibilityNodeObject::menuForMenuButton() const @@ -1228,7 +1229,7 @@ Element* AccessibilityNodeObject::menuItemElementForMenu() const if (ariaRoleAttribute() != MenuRole) return nullptr; - return siblingWithAriaRole("menuitem", node()); + return siblingWithAriaRole(node(), "menuitem"); } AccessibilityObject* AccessibilityNodeObject::menuButtonForMenu() const diff --git a/Source/WebCore/css/CSSParser.cpp b/Source/WebCore/css/CSSParser.cpp index ad77ae7a960e..bc4a76094209 100644 --- a/Source/WebCore/css/CSSParser.cpp +++ b/Source/WebCore/css/CSSParser.cpp @@ -1310,7 +1310,7 @@ RefPtr CSSParser::parseFontFaceValue(const AtomicString& string) RefPtr value; for (auto propertyID : { CSSValueSerif, CSSValueSansSerif, CSSValueCursive, CSSValueFantasy, CSSValueMonospace, CSSValueWebkitBody }) { - if (equalIgnoringCase(stripped, getValueName(propertyID))) { + if (equalIgnoringASCIICase(stripped, getValueName(propertyID))) { value = cssValuePool.createIdentifierValue(propertyID); break; } diff --git a/Source/WebCore/css/CSSParserValues.h b/Source/WebCore/css/CSSParserValues.h index ecb79ac53ad4..4845a242a527 100644 --- a/Source/WebCore/css/CSSParserValues.h +++ b/Source/WebCore/css/CSSParserValues.h @@ -89,13 +89,6 @@ struct CSSParserString { return m_data.characters16[i]; } - bool equalIgnoringCase(const char* str) const - { - if (is8Bit()) - return WTF::equalIgnoringCase(str, characters8(), length()); - return WTF::equalIgnoringCase(str, characters16(), length()); - } - operator String() const { return is8Bit() ? String(m_data.characters8, m_length) : String(m_data.characters16, m_length); } operator AtomicString() const { return is8Bit() ? AtomicString(m_data.characters8, m_length) : AtomicString(m_data.characters16, m_length); } diff --git a/Source/WebCore/css/MediaQueryEvaluator.cpp b/Source/WebCore/css/MediaQueryEvaluator.cpp index 99b54ae07398..ee25de17661a 100644 --- a/Source/WebCore/css/MediaQueryEvaluator.cpp +++ b/Source/WebCore/css/MediaQueryEvaluator.cpp @@ -105,7 +105,7 @@ bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const { return mediaTypeToMatch.isEmpty() || equalLettersIgnoringASCIICase(mediaTypeToMatch, "all") - || equalIgnoringCase(mediaTypeToMatch, m_mediaType); + || equalIgnoringASCIICase(mediaTypeToMatch, m_mediaType); } bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) const @@ -114,7 +114,7 @@ bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) c ASSERT(mediaTypeToMatch); ASSERT(mediaTypeToMatch[0] != '\0'); ASSERT(!equalLettersIgnoringASCIICase(StringView(mediaTypeToMatch), "all")); - return equalIgnoringCase(mediaTypeToMatch, m_mediaType); + return equalIgnoringASCIICase(m_mediaType, mediaTypeToMatch); } static bool applyRestrictor(MediaQuery::Restrictor r, bool value) diff --git a/Source/WebCore/dom/DataTransfer.cpp b/Source/WebCore/dom/DataTransfer.cpp index 2f3b0503d610..0c8f2cbae9bd 100644 --- a/Source/WebCore/dom/DataTransfer.cpp +++ b/Source/WebCore/dom/DataTransfer.cpp @@ -189,7 +189,7 @@ bool DataTransfer::hasFileOfType(const String& type) ASSERT_WITH_SECURITY_IMPLICATION(canReadTypes()); for (const String& path : m_pasteboard->readFilenames()) { - if (equalIgnoringCase(File::contentTypeForFile(path), type)) + if (equalIgnoringASCIICase(File::contentTypeForFile(path), type)) return true; } diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 0e7c61fff63f..98d7a7510a5a 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -3342,7 +3342,7 @@ void Document::processViewport(const String& features, ViewportArguments::Type o return; m_viewportArguments = ViewportArguments(origin); - processArguments(features, (void*)&m_viewportArguments, &setViewportFeature); + processArguments(features, (void*)&m_viewportArguments, setViewportFeature); updateViewportArguments(); } @@ -3361,6 +3361,7 @@ void Document::updateViewportArguments() } #if PLATFORM(IOS) + // FIXME: Find a better place for this functionality. void setParserFeature(const String& key, const String& value, Document* document, void*) { @@ -3371,7 +3372,7 @@ void setParserFeature(const String& key, const String& value, Document* document void Document::processFormatDetection(const String& features) { ASSERT(!features.isNull()); - processArguments(features, nullptr, &setParserFeature); + processArguments(features, nullptr, setParserFeature); } void Document::processWebAppOrientations() @@ -3379,6 +3380,7 @@ void Document::processWebAppOrientations() if (Page* page = this->page()) page->chrome().client().webAppOrientationsUpdated(); } + #endif void Document::processReferrerPolicy(const String& policy) @@ -4394,7 +4396,7 @@ void Document::setDomain(const String& newDomain, ExceptionCode& ec) // assigns its current domain using document.domain, the page will // allow other pages loaded on different ports in the same domain that // have also assigned to access this page. - if (equalIgnoringCase(domain(), newDomain)) { + if (equalIgnoringASCIICase(domain(), newDomain)) { securityOrigin()->setDomainFromDOM(newDomain); return; } diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index 34201766dfe4..f5c77a97a13c 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -438,19 +438,24 @@ ALWAYS_INLINE void Element::synchronizeAttribute(const QualifiedName& name) cons } } +static ALWAYS_INLINE bool isStyleAttribute(const Element& element, const AtomicString& attributeLocalName) +{ + if (shouldIgnoreAttributeCase(element)) + return equalLettersIgnoringASCIICase(attributeLocalName, "style"); + return attributeLocalName == styleAttr.localName(); +} + ALWAYS_INLINE void Element::synchronizeAttribute(const AtomicString& localName) const { // This version of synchronizeAttribute() is streamlined for the case where you don't have a full QualifiedName, // e.g when called from DOM API. if (!elementData()) return; - // FIXME: this should be comparing in the ASCII range. - if (elementData()->styleAttributeIsDirty() && equalPossiblyIgnoringCase(localName, styleAttr.localName(), shouldIgnoreAttributeCase(*this))) { + if (elementData()->styleAttributeIsDirty() && isStyleAttribute(*this, localName)) { ASSERT_WITH_SECURITY_IMPLICATION(isStyledElement()); static_cast(this)->synchronizeStyleAttributeInternal(); return; } - if (elementData()->animatedSVGAttributesAreDirty()) { // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well. ASSERT_WITH_SECURITY_IMPLICATION(isSVGElement()); @@ -2882,7 +2887,6 @@ SpellcheckAttributeState Element::spellcheckAttributeState() const return SpellcheckAttributeTrue; if (equalLettersIgnoringASCIICase(value, "false")) return SpellcheckAttributeFalse; - return SpellcheckAttributeDefault; } diff --git a/Source/WebCore/dom/TreeScope.cpp b/Source/WebCore/dom/TreeScope.cpp index 12388f14c3f5..d46a3a6d8d00 100644 --- a/Source/WebCore/dom/TreeScope.cpp +++ b/Source/WebCore/dom/TreeScope.cpp @@ -270,8 +270,10 @@ Element* TreeScope::findAnchor(const String& name) return element; for (auto& anchor : descendantsOfType(m_rootNode)) { if (m_rootNode.document().inQuirksMode()) { - // Quirks mode, case insensitive comparison of names. - if (equalIgnoringCase(anchor.name(), name)) + // Quirks mode, ASCII case-insensitive comparison of names. + // FIXME: This behavior is not mentioned in the HTML specification. + // We should either remove this or get this into the specification. + if (equalIgnoringASCIICase(anchor.name(), name)) return &anchor; } else { // Strict mode, names need to match exactly. diff --git a/Source/WebCore/html/HiddenInputType.cpp b/Source/WebCore/html/HiddenInputType.cpp index d6ee167981a0..a4c9c4bc5ba4 100644 --- a/Source/WebCore/html/HiddenInputType.cpp +++ b/Source/WebCore/html/HiddenInputType.cpp @@ -99,7 +99,7 @@ bool HiddenInputType::isHiddenType() const bool HiddenInputType::appendFormData(FormDataList& encoding, bool isMultipartForm) const { - if (equalIgnoringCase(element().name(), "_charset_")) { + if (equalIgnoringASCIICase(element().name(), "_charset_")) { encoding.appendData(element().name(), String(encoding.encoding().name())); return true; } diff --git a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp index acc67d8d34ee..53c8856604c1 100644 --- a/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGL2RenderingContext.cpp @@ -950,7 +950,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) if (isContextLostOrPending()) return nullptr; - if ((equalIgnoringCase(name, "EXT_texture_filter_anisotropic") || equalIgnoringCase(name, "WEBKIT_EXT_texture_filter_anisotropic")) + if ((equalIgnoringASCIICase(name, "EXT_texture_filter_anisotropic") || equalIgnoringASCIICase(name, "WEBKIT_EXT_texture_filter_anisotropic")) && m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic")) { if (!m_extTextureFilterAnisotropic) { m_context->getExtensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic"); @@ -958,7 +958,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_extTextureFilterAnisotropic.get(); } - if (equalIgnoringCase(name, "OES_texture_float") + if (equalIgnoringASCIICase(name, "OES_texture_float") && m_context->getExtensions()->supports("GL_OES_texture_float")) { if (!m_oesTextureFloat) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_float"); @@ -966,7 +966,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_oesTextureFloat.get(); } - if (equalIgnoringCase(name, "OES_texture_float_linear") + if (equalIgnoringASCIICase(name, "OES_texture_float_linear") && m_context->getExtensions()->supports("GL_OES_texture_float_linear")) { if (!m_oesTextureFloatLinear) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_float_linear"); @@ -974,7 +974,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_oesTextureFloatLinear.get(); } - if (equalIgnoringCase(name, "OES_texture_half_float") + if (equalIgnoringASCIICase(name, "OES_texture_half_float") && m_context->getExtensions()->supports("GL_OES_texture_half_float")) { if (!m_oesTextureHalfFloat) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float"); @@ -982,7 +982,7 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_oesTextureHalfFloat.get(); } - if (equalIgnoringCase(name, "OES_texture_half_float_linear") + if (equalIgnoringASCIICase(name, "OES_texture_half_float_linear") && m_context->getExtensions()->supports("GL_OES_texture_half_float_linear")) { if (!m_oesTextureHalfFloatLinear) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float_linear"); @@ -990,30 +990,30 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_oesTextureHalfFloatLinear.get(); } - if (equalIgnoringCase(name, "WEBGL_lose_context")) { + if (equalIgnoringASCIICase(name, "WEBGL_lose_context")) { if (!m_webglLoseContext) m_webglLoseContext = std::make_unique(this); return m_webglLoseContext.get(); } - if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_atc")) + if ((equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_atc")) && WebGLCompressedTextureATC::supported(this)) { if (!m_webglCompressedTextureATC) m_webglCompressedTextureATC = std::make_unique(this); return m_webglCompressedTextureATC.get(); } - if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) + if ((equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) && WebGLCompressedTexturePVRTC::supported(this)) { if (!m_webglCompressedTexturePVRTC) m_webglCompressedTexturePVRTC = std::make_unique(this); return m_webglCompressedTexturePVRTC.get(); } - if (equalIgnoringCase(name, "WEBGL_compressed_texture_s3tc") + if (equalIgnoringASCIICase(name, "WEBGL_compressed_texture_s3tc") && WebGLCompressedTextureS3TC::supported(this)) { if (!m_webglCompressedTextureS3TC) m_webglCompressedTextureS3TC = std::make_unique(this); return m_webglCompressedTextureS3TC.get(); } - if (equalIgnoringCase(name, "WEBGL_depth_texture") + if (equalIgnoringASCIICase(name, "WEBGL_depth_texture") && WebGLDepthTexture::supported(graphicsContext3D())) { if (!m_webglDepthTexture) { m_context->getExtensions()->ensureEnabled("GL_CHROMIUM_depth_texture"); @@ -1021,12 +1021,12 @@ WebGLExtension* WebGL2RenderingContext::getExtension(const String& name) } return m_webglDepthTexture.get(); } - if (equalIgnoringCase(name, "WEBGL_debug_renderer_info")) { + if (equalIgnoringASCIICase(name, "WEBGL_debug_renderer_info")) { if (!m_webglDebugRendererInfo) m_webglDebugRendererInfo = std::make_unique(this); return m_webglDebugRendererInfo.get(); } - if (equalIgnoringCase(name, "WEBGL_debug_shaders") + if (equalIgnoringASCIICase(name, "WEBGL_debug_shaders") && m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source")) { if (!m_webglDebugShaders) m_webglDebugShaders = std::make_unique(this); diff --git a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp index ec1152a34821..11e13e1001c7 100644 --- a/Source/WebCore/html/canvas/WebGLRenderingContext.cpp +++ b/Source/WebCore/html/canvas/WebGLRenderingContext.cpp @@ -89,7 +89,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) if (isContextLostOrPending()) return nullptr; - if (equalIgnoringCase(name, "EXT_blend_minmax") + if (equalIgnoringASCIICase(name, "EXT_blend_minmax") && m_context->getExtensions()->supports("GL_EXT_blend_minmax")) { if (!m_extBlendMinMax) { m_context->getExtensions()->ensureEnabled("GL_EXT_blend_minmax"); @@ -97,7 +97,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_extBlendMinMax.get(); } - if (equalIgnoringCase(name, "EXT_sRGB") + if (equalIgnoringASCIICase(name, "EXT_sRGB") && m_context->getExtensions()->supports("GL_EXT_sRGB")) { if (!m_extsRGB) { m_context->getExtensions()->ensureEnabled("GL_EXT_sRGB"); @@ -105,7 +105,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_extsRGB.get(); } - if (equalIgnoringCase(name, "EXT_frag_depth") + if (equalIgnoringASCIICase(name, "EXT_frag_depth") && m_context->getExtensions()->supports("GL_EXT_frag_depth")) { if (!m_extFragDepth) { m_context->getExtensions()->ensureEnabled("GL_EXT_frag_depth"); @@ -113,7 +113,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_extFragDepth.get(); } - if (equalIgnoringCase(name, "EXT_shader_texture_lod") + if (equalIgnoringASCIICase(name, "EXT_shader_texture_lod") && (m_context->getExtensions()->supports("GL_EXT_shader_texture_lod") || m_context->getExtensions()->supports("GL_ARB_shader_texture_lod"))) { if (!m_extShaderTextureLOD) { m_context->getExtensions()->ensureEnabled("GL_EXT_shader_texture_lod"); @@ -121,7 +121,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_extShaderTextureLOD.get(); } - if ((equalIgnoringCase(name, "EXT_texture_filter_anisotropic") || equalIgnoringCase(name, "WEBKIT_EXT_texture_filter_anisotropic")) + if ((equalIgnoringASCIICase(name, "EXT_texture_filter_anisotropic") || equalIgnoringASCIICase(name, "WEBKIT_EXT_texture_filter_anisotropic")) && m_context->getExtensions()->supports("GL_EXT_texture_filter_anisotropic")) { if (!m_extTextureFilterAnisotropic) { m_context->getExtensions()->ensureEnabled("GL_EXT_texture_filter_anisotropic"); @@ -129,7 +129,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_extTextureFilterAnisotropic.get(); } - if (equalIgnoringCase(name, "OES_standard_derivatives") + if (equalIgnoringASCIICase(name, "OES_standard_derivatives") && m_context->getExtensions()->supports("GL_OES_standard_derivatives")) { if (!m_oesStandardDerivatives) { m_context->getExtensions()->ensureEnabled("GL_OES_standard_derivatives"); @@ -137,7 +137,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesStandardDerivatives.get(); } - if (equalIgnoringCase(name, "OES_texture_float") + if (equalIgnoringASCIICase(name, "OES_texture_float") && m_context->getExtensions()->supports("GL_OES_texture_float")) { if (!m_oesTextureFloat) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_float"); @@ -145,7 +145,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesTextureFloat.get(); } - if (equalIgnoringCase(name, "OES_texture_float_linear") + if (equalIgnoringASCIICase(name, "OES_texture_float_linear") && m_context->getExtensions()->supports("GL_OES_texture_float_linear")) { if (!m_oesTextureFloatLinear) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_float_linear"); @@ -153,7 +153,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesTextureFloatLinear.get(); } - if (equalIgnoringCase(name, "OES_texture_half_float") + if (equalIgnoringASCIICase(name, "OES_texture_half_float") && m_context->getExtensions()->supports("GL_OES_texture_half_float")) { if (!m_oesTextureHalfFloat) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float"); @@ -161,7 +161,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesTextureHalfFloat.get(); } - if (equalIgnoringCase(name, "OES_texture_half_float_linear") + if (equalIgnoringASCIICase(name, "OES_texture_half_float_linear") && m_context->getExtensions()->supports("GL_OES_texture_half_float_linear")) { if (!m_oesTextureHalfFloatLinear) { m_context->getExtensions()->ensureEnabled("GL_OES_texture_half_float_linear"); @@ -169,7 +169,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesTextureHalfFloatLinear.get(); } - if (equalIgnoringCase(name, "OES_vertex_array_object") + if (equalIgnoringASCIICase(name, "OES_vertex_array_object") && m_context->getExtensions()->supports("GL_OES_vertex_array_object")) { if (!m_oesVertexArrayObject) { m_context->getExtensions()->ensureEnabled("GL_OES_vertex_array_object"); @@ -177,7 +177,7 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesVertexArrayObject.get(); } - if (equalIgnoringCase(name, "OES_element_index_uint") + if (equalIgnoringASCIICase(name, "OES_element_index_uint") && m_context->getExtensions()->supports("GL_OES_element_index_uint")) { if (!m_oesElementIndexUint) { m_context->getExtensions()->ensureEnabled("GL_OES_element_index_uint"); @@ -185,30 +185,30 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_oesElementIndexUint.get(); } - if (equalIgnoringCase(name, "WEBGL_lose_context")) { + if (equalIgnoringASCIICase(name, "WEBGL_lose_context")) { if (!m_webglLoseContext) m_webglLoseContext = std::make_unique(this); return m_webglLoseContext.get(); } - if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_atc")) + if ((equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_atc")) && WebGLCompressedTextureATC::supported(this)) { if (!m_webglCompressedTextureATC) m_webglCompressedTextureATC = std::make_unique(this); return m_webglCompressedTextureATC.get(); } - if ((equalIgnoringCase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) + if ((equalIgnoringASCIICase(name, "WEBKIT_WEBGL_compressed_texture_pvrtc")) && WebGLCompressedTexturePVRTC::supported(this)) { if (!m_webglCompressedTexturePVRTC) m_webglCompressedTexturePVRTC = std::make_unique(this); return m_webglCompressedTexturePVRTC.get(); } - if (equalIgnoringCase(name, "WEBGL_compressed_texture_s3tc") + if (equalIgnoringASCIICase(name, "WEBGL_compressed_texture_s3tc") && WebGLCompressedTextureS3TC::supported(this)) { if (!m_webglCompressedTextureS3TC) m_webglCompressedTextureS3TC = std::make_unique(this); return m_webglCompressedTextureS3TC.get(); } - if (equalIgnoringCase(name, "WEBGL_depth_texture") + if (equalIgnoringASCIICase(name, "WEBGL_depth_texture") && WebGLDepthTexture::supported(graphicsContext3D())) { if (!m_webglDepthTexture) { m_context->getExtensions()->ensureEnabled("GL_CHROMIUM_depth_texture"); @@ -216,26 +216,26 @@ WebGLExtension* WebGLRenderingContext::getExtension(const String& name) } return m_webglDepthTexture.get(); } - if (equalIgnoringCase(name, "WEBGL_draw_buffers") && supportsDrawBuffers()) { + if (equalIgnoringASCIICase(name, "WEBGL_draw_buffers") && supportsDrawBuffers()) { if (!m_webglDrawBuffers) { m_context->getExtensions()->ensureEnabled("GL_EXT_draw_buffers"); m_webglDrawBuffers = std::make_unique(this); } return m_webglDrawBuffers.get(); } - if (equalIgnoringCase(name, "ANGLE_instanced_arrays") && ANGLEInstancedArrays::supported(this)) { + if (equalIgnoringASCIICase(name, "ANGLE_instanced_arrays") && ANGLEInstancedArrays::supported(this)) { if (!m_angleInstancedArrays) { m_context->getExtensions()->ensureEnabled("GL_ANGLE_instanced_arrays"); m_angleInstancedArrays = std::make_unique(this); } return m_angleInstancedArrays.get(); } - if (equalIgnoringCase(name, "WEBGL_debug_renderer_info")) { + if (equalIgnoringASCIICase(name, "WEBGL_debug_renderer_info")) { if (!m_webglDebugRendererInfo) m_webglDebugRendererInfo = std::make_unique(this); return m_webglDebugRendererInfo.get(); } - if (equalIgnoringCase(name, "WEBGL_debug_shaders") + if (equalIgnoringASCIICase(name, "WEBGL_debug_shaders") && m_context->getExtensions()->supports("GL_ANGLE_translated_shader_source")) { if (!m_webglDebugShaders) m_webglDebugShaders = std::make_unique(this); diff --git a/Source/WebCore/html/parser/CSSPreloadScanner.cpp b/Source/WebCore/html/parser/CSSPreloadScanner.cpp index 75a7a93b1bc5..9a64c51b6208 100644 --- a/Source/WebCore/html/parser/CSSPreloadScanner.cpp +++ b/Source/WebCore/html/parser/CSSPreloadScanner.cpp @@ -195,25 +195,18 @@ static String parseCSSStringOrURL(const UChar* characters, size_t length) return String(characters + offset, reducedLength); } -template -static inline bool ruleEqualIgnoringCase(const Vector& rule, const char (&reference)[referenceLength]) -{ - unsigned referenceCharactersLength = referenceLength - 1; - return rule.size() == referenceCharactersLength && equalIgnoringCase(reference, rule.data(), referenceCharactersLength); -} - void CSSPreloadScanner::emitRule() { - if (ruleEqualIgnoringCase(m_rule, "import")) { + StringView rule(m_rule.data(), m_rule.size()); + if (equalLettersIgnoringASCIICase(rule, "import")) { String url = parseCSSStringOrURL(m_ruleValue.data(), m_ruleValue.size()); if (!url.isEmpty()) { - URL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScaner via scan()! - + URL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScanner via scan(): without it we will get relative URLs wrong. // FIXME: Should this be including the charset in the preload request? m_requests->append(std::make_unique("css", url, baseElementURL, CachedResource::CSSStyleSheet, String())); } m_state = Initial; - } else if (ruleEqualIgnoringCase(m_rule, "charset")) + } else if (equalLettersIgnoringASCIICase(rule, "charset")) m_state = Initial; else m_state = DoneParsingImportRules; diff --git a/Source/WebCore/inspector/InspectorNodeFinder.cpp b/Source/WebCore/inspector/InspectorNodeFinder.cpp index 1edbbfcac438..d37e855c93f3 100644 --- a/Source/WebCore/inspector/InspectorNodeFinder.cpp +++ b/Source/WebCore/inspector/InspectorNodeFinder.cpp @@ -113,7 +113,7 @@ bool InspectorNodeFinder::matchesElement(const Element& element) { String nodeName = element.nodeName(); if ((!m_startTagFound && !m_endTagFound && (nodeName.findIgnoringCase(m_tagNameQuery) != notFound)) - || (m_startTagFound && m_endTagFound && equalIgnoringCase(nodeName, m_tagNameQuery)) + || (m_startTagFound && m_endTagFound && equalIgnoringASCIICase(nodeName, m_tagNameQuery)) || (m_startTagFound && !m_endTagFound && nodeName.startsWith(m_tagNameQuery, false)) || (!m_startTagFound && m_endTagFound && nodeName.endsWith(m_tagNameQuery, false))) return true; diff --git a/Source/WebCore/loader/HistoryController.cpp b/Source/WebCore/loader/HistoryController.cpp index 3a6ea716f29a..53ee1201548c 100644 --- a/Source/WebCore/loader/HistoryController.cpp +++ b/Source/WebCore/loader/HistoryController.cpp @@ -606,7 +606,7 @@ bool HistoryController::currentItemShouldBeReplaced() const // "If the browsing context's session history contains only one Document, // and that was the about:blank Document created when the browsing context // was created, then the navigation must be done with replacement enabled." - return m_currentItem && !m_previousItem && equalIgnoringCase(m_currentItem->urlString(), blankURL()); + return m_currentItem && !m_previousItem && equalIgnoringASCIICase(m_currentItem->urlString(), blankURL()); } void HistoryController::clearPreviousItem() diff --git a/Source/WebCore/loader/SubframeLoader.cpp b/Source/WebCore/loader/SubframeLoader.cpp index 0de434c73376..5a09cfd533ef 100644 --- a/Source/WebCore/loader/SubframeLoader.cpp +++ b/Source/WebCore/loader/SubframeLoader.cpp @@ -173,7 +173,7 @@ static String findPluginMIMETypeFromURL(Page* page, const String& url) pluginData.getWebVisibleMimesAndPluginIndices(mimes, mimePluginIndices); for (auto& mime : mimes) { for (auto& mimeExtension : mime.extensions) { - if (equalIgnoringCase(extension, mimeExtension)) + if (equalIgnoringASCIICase(extension, mimeExtension)) return mime.type; } } diff --git a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp index 88e7ee2b2531..847b07126f54 100644 --- a/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp +++ b/Source/WebCore/loader/appcache/ApplicationCacheHost.cpp @@ -378,7 +378,7 @@ bool ApplicationCacheHost::shouldLoadResourceFromApplicationCache(const Resource // If the resource is not to be fetched using the HTTP GET mechanism or equivalent, or if its URL has a different // component than the application cache's manifest, then fetch the resource normally. - if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringCase(request.url().protocol(), cache->manifestResource()->url().protocol())) + if (!ApplicationCache::requestIsHTTPOrHTTPSGet(request) || !equalIgnoringASCIICase(request.url().protocol(), cache->manifestResource()->url().protocol())) return false; // If the resource's URL is an master entry, the manifest, an explicit entry, or a fallback entry diff --git a/Source/WebCore/loader/appcache/ManifestParser.cpp b/Source/WebCore/loader/appcache/ManifestParser.cpp index 2c6144f8a109..601141d6ff66 100644 --- a/Source/WebCore/loader/appcache/ManifestParser.cpp +++ b/Source/WebCore/loader/appcache/ManifestParser.cpp @@ -122,7 +122,7 @@ bool parseManifest(const URL& manifestURL, const char* data, int length, Manifes if (url.hasFragmentIdentifier()) url.removeFragmentIdentifier(); - if (!equalIgnoringCase(url.protocol(), manifestURL.protocol())) + if (!equalIgnoringASCIICase(url.protocol(), manifestURL.protocol())) continue; if (mode == Explicit && manifestURL.protocolIs("https") && !protocolHostAndPortAreEqual(manifestURL, url)) diff --git a/Source/WebCore/page/OriginAccessEntry.h b/Source/WebCore/page/OriginAccessEntry.h index 183600bde5f2..06614e12d089 100644 --- a/Source/WebCore/page/OriginAccessEntry.h +++ b/Source/WebCore/page/OriginAccessEntry.h @@ -61,7 +61,7 @@ class OriginAccessEntry { inline bool operator==(const OriginAccessEntry& a, const OriginAccessEntry& b) { - return equalIgnoringCase(a.protocol(), b.protocol()) && equalIgnoringCase(a.host(), b.host()) && a.subdomainSettings() == b.subdomainSettings(); + return equalIgnoringASCIICase(a.protocol(), b.protocol()) && equalIgnoringASCIICase(a.host(), b.host()) && a.subdomainSettings() == b.subdomainSettings(); } inline bool operator!=(const OriginAccessEntry& a, const OriginAccessEntry& b) diff --git a/Source/WebCore/page/Performance.cpp b/Source/WebCore/page/Performance.cpp index a3e2cf614856..ed39a1d15081 100644 --- a/Source/WebCore/page/Performance.cpp +++ b/Source/WebCore/page/Performance.cpp @@ -140,21 +140,22 @@ PassRefPtr Performance::webkitGetEntriesByName(const Strin RefPtr entries = PerformanceEntryList::create(); #if ENABLE(RESOURCE_TIMING) - if (entryType.isNull() || equalIgnoringCase(entryType, "resource")) + if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "resource")) { for (auto& resource : m_resourceTimingBuffer) { if (resource->name() == name) entries->append(resource); } -#endif // ENABLE(RESOURCE_TIMING) + } +#endif #if ENABLE(USER_TIMING) if (m_userTiming) { - if (entryType.isNull() || equalIgnoringCase(entryType, "mark")) + if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "mark")) entries->appendAll(m_userTiming->getMarks(name)); - if (entryType.isNull() || equalIgnoringCase(entryType, "measure")) + if (entryType.isNull() || equalLettersIgnoringASCIICase(entryType, "measure")) entries->appendAll(m_userTiming->getMeasures(name)); } -#endif // ENABLE(USER_TIMING) +#endif entries->sort(); return entries; diff --git a/Source/WebCore/page/UserContentURLPattern.cpp b/Source/WebCore/page/UserContentURLPattern.cpp index 9dba91c5e702..953ce0ff4785 100644 --- a/Source/WebCore/page/UserContentURLPattern.cpp +++ b/Source/WebCore/page/UserContentURLPattern.cpp @@ -114,7 +114,7 @@ bool UserContentURLPattern::matches(const URL& test) const if (m_invalid) return false; - if (!equalIgnoringCase(test.protocol(), m_scheme)) + if (!equalIgnoringASCIICase(test.protocol(), m_scheme)) return false; if (!equalLettersIgnoringASCIICase(m_scheme, "file") && !matchesHost(test)) @@ -126,7 +126,7 @@ bool UserContentURLPattern::matches(const URL& test) const bool UserContentURLPattern::matchesHost(const URL& test) const { const String& host = test.host(); - if (equalIgnoringCase(host, m_host)) + if (equalIgnoringASCIICase(host, m_host)) return true; if (!m_matchSubdomains) diff --git a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp index b3c61bf867f2..9f112f0c457d 100644 --- a/Source/WebCore/page/csp/ContentSecurityPolicy.cpp +++ b/Source/WebCore/page/csp/ContentSecurityPolicy.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2011 Google, Inc. All rights reserved. - * Copyright (C) 2013 Apple Inc. All rights reserved. + * Copyright (C) 2013, 2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -125,26 +125,39 @@ static const char pluginTypes[] = "plugin-types"; static const char reflectedXSS[] = "reflected-xss"; #endif -bool isDirectiveName(const String& name) -{ - return (equalIgnoringCase(name, connectSrc) - || equalIgnoringCase(name, defaultSrc) - || equalIgnoringCase(name, fontSrc) - || equalIgnoringCase(name, frameSrc) - || equalIgnoringCase(name, imgSrc) - || equalIgnoringCase(name, mediaSrc) - || equalIgnoringCase(name, objectSrc) - || equalIgnoringCase(name, reportURI) - || equalIgnoringCase(name, sandbox) - || equalIgnoringCase(name, scriptSrc) - || equalIgnoringCase(name, styleSrc) #if ENABLE(CSP_NEXT) - || equalIgnoringCase(name, baseURI) - || equalIgnoringCase(name, formAction) - || equalIgnoringCase(name, pluginTypes) - || equalIgnoringCase(name, reflectedXSS) + +static inline bool isExperimentalDirectiveName(const String& name) +{ + return equalLettersIgnoringASCIICase(name, baseURI) + || equalLettersIgnoringASCIICase(name, formAction) + || equalLettersIgnoringASCIICase(name, pluginTypes) + || equalLettersIgnoringASCIICase(name, reflectedXSS); +} + +#else + +static inline bool isExperimentalDirectiveName(const String&) +{ + return false; +} + #endif - ); + +bool isDirectiveName(const String& name) +{ + return equalLettersIgnoringASCIICase(name, connectSrc) + || equalLettersIgnoringASCIICase(name, defaultSrc) + || equalLettersIgnoringASCIICase(name, fontSrc) + || equalLettersIgnoringASCIICase(name, frameSrc) + || equalLettersIgnoringASCIICase(name, imgSrc) + || equalLettersIgnoringASCIICase(name, mediaSrc) + || equalLettersIgnoringASCIICase(name, objectSrc) + || equalLettersIgnoringASCIICase(name, reportURI) + || equalLettersIgnoringASCIICase(name, sandbox) + || equalLettersIgnoringASCIICase(name, scriptSrc) + || equalLettersIgnoringASCIICase(name, styleSrc) + || isExperimentalDirectiveName(name); } } // namespace @@ -190,7 +203,7 @@ static bool isSourceListNone(const String& value) const UChar* position = begin; skipWhile(position, end); - if (!equalIgnoringCase("'none'", begin, position - begin)) + if (!equalLettersIgnoringASCIICase(begin, position - begin, "'none'")) return false; skipWhile(position, end); @@ -228,18 +241,18 @@ class CSPSource { if (m_scheme.isEmpty()) { String protectedResourceScheme(m_policy->securityOrigin()->protocol()); #if ENABLE(CSP_NEXT) - if (equalIgnoringCase("http", protectedResourceScheme)) + if (equalLettersIgnoringASCIICase(protectedResourceScheme, "http")) return url.protocolIsInHTTPFamily(); #endif - return equalIgnoringCase(url.protocol(), protectedResourceScheme); + return equalIgnoringASCIICase(url.protocol(), protectedResourceScheme); } - return equalIgnoringCase(url.protocol(), m_scheme); + return equalIgnoringASCIICase(url.protocol(), m_scheme); } bool hostMatches(const URL& url) const { const String& host = url.host(); - if (equalIgnoringCase(host, m_host)) + if (equalIgnoringASCIICase(host, m_host)) return true; return m_hostHasWildcard && host.endsWith("." + m_host, false); @@ -393,14 +406,12 @@ void CSPSourceList::parse(const UChar* begin, const UChar* end) // / ( [ scheme "://" ] host [ port ] [ path ] ) // / "'self'" // -bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, - String& scheme, String& host, int& port, String& path, - bool& hostHasWildcard, bool& portHasWildcard) +bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, String& scheme, String& host, int& port, String& path, bool& hostHasWildcard, bool& portHasWildcard) { if (begin == end) return false; - if (equalIgnoringCase("'none'", begin, end - begin)) + if (equalLettersIgnoringASCIICase(begin, end - begin, "'none'")) return false; if (end - begin == 1 && *begin == '*') { @@ -408,17 +419,17 @@ bool CSPSourceList::parseSource(const UChar* begin, const UChar* end, return true; } - if (equalIgnoringCase("'self'", begin, end - begin)) { + if (equalLettersIgnoringASCIICase(begin, end - begin, "'self'")) { addSourceSelf(); return true; } - if (equalIgnoringCase("'unsafe-inline'", begin, end - begin)) { + if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-inline'")) { addSourceUnsafeInline(); return true; } - if (equalIgnoringCase("'unsafe-eval'", begin, end - begin)) { + if (equalLettersIgnoringASCIICase(begin, end - begin, "'unsafe-eval'")) { addSourceUnsafeEval(); return true; } @@ -963,7 +974,7 @@ bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* direct if (checkSource(directive, url)) return true; - String prefix; + const char* prefix; if (baseURI == effectiveDirective) prefix = "Refused to set the document's base URI to '"; else if (connectSrc == effectiveDirective) @@ -984,12 +995,14 @@ bool CSPDirectiveList::checkSourceAndReportViolation(SourceListDirective* direct prefix = "Refused to load the script '"; else if (styleSrc == effectiveDirective) prefix = "Refused to load the stylesheet '"; + else + prefix = ""; - String suffix = String(); + String suffix; if (directive == m_defaultSrc.get()) suffix = " Note that '" + effectiveDirective + "' was not explicitly set, so 'default-src' is used as a fallback."; - reportViolation(directive->text(), effectiveDirective, prefix + url.stringCenterEllipsizedToLength() + "' because it violates the following Content Security Policy directive: \"" + directive->text() + "\"." + suffix + "\n", url); + reportViolation(directive->text(), effectiveDirective, makeString(prefix, url.stringCenterEllipsizedToLength(), "' because it violates the following Content Security Policy directive: \"", directive->text(), "\".", suffix, '\n'), url); return denyIfEnforcingPolicy(); } @@ -1275,11 +1288,11 @@ void CSPDirectiveList::parseReflectedXSS(const String& name, const String& value // value1 // ^ - if (equalIgnoringCase("allow", begin, position - begin)) + if (equalLettersIgnoringASCIICase(begin, position - begin, "allow")) m_reflectedXSSDisposition = ContentSecurityPolicy::AllowReflectedXSS; - else if (equalIgnoringCase("filter", begin, position - begin)) + else if (equalLettersIgnoringASCIICase(begin, position - begin, "filter")) m_reflectedXSSDisposition = ContentSecurityPolicy::FilterReflectedXSS; - else if (equalIgnoringCase("block", begin, position - begin)) + else if (equalLettersIgnoringASCIICase(begin, position - begin, "block")) m_reflectedXSSDisposition = ContentSecurityPolicy::BlockReflectedXSS; else { m_reflectedXSSDisposition = ContentSecurityPolicy::ReflectedXSSInvalid; @@ -1301,37 +1314,37 @@ void CSPDirectiveList::addDirective(const String& name, const String& value) { ASSERT(!name.isEmpty()); - if (equalIgnoringCase(name, defaultSrc)) + if (equalLettersIgnoringASCIICase(name, defaultSrc)) setCSPDirective(name, value, m_defaultSrc); - else if (equalIgnoringCase(name, scriptSrc)) + else if (equalLettersIgnoringASCIICase(name, scriptSrc)) setCSPDirective(name, value, m_scriptSrc); - else if (equalIgnoringCase(name, objectSrc)) + else if (equalLettersIgnoringASCIICase(name, objectSrc)) setCSPDirective(name, value, m_objectSrc); - else if (equalIgnoringCase(name, frameSrc)) + else if (equalLettersIgnoringASCIICase(name, frameSrc)) setCSPDirective(name, value, m_frameSrc); - else if (equalIgnoringCase(name, imgSrc)) + else if (equalLettersIgnoringASCIICase(name, imgSrc)) setCSPDirective(name, value, m_imgSrc); - else if (equalIgnoringCase(name, styleSrc)) + else if (equalLettersIgnoringASCIICase(name, styleSrc)) setCSPDirective(name, value, m_styleSrc); - else if (equalIgnoringCase(name, fontSrc)) + else if (equalLettersIgnoringASCIICase(name, fontSrc)) setCSPDirective(name, value, m_fontSrc); - else if (equalIgnoringCase(name, mediaSrc)) + else if (equalLettersIgnoringASCIICase(name, mediaSrc)) setCSPDirective(name, value, m_mediaSrc); - else if (equalIgnoringCase(name, connectSrc)) + else if (equalLettersIgnoringASCIICase(name, connectSrc)) setCSPDirective(name, value, m_connectSrc); - else if (equalIgnoringCase(name, sandbox)) + else if (equalLettersIgnoringASCIICase(name, sandbox)) applySandboxPolicy(name, value); - else if (equalIgnoringCase(name, reportURI)) + else if (equalLettersIgnoringASCIICase(name, reportURI)) parseReportURI(name, value); #if ENABLE(CSP_NEXT) else if (m_policy->experimentalFeaturesEnabled()) { - if (equalIgnoringCase(name, baseURI)) + if (equalLettersIgnoringASCIICase(name, baseURI)) setCSPDirective(name, value, m_baseURI); - else if (equalIgnoringCase(name, formAction)) + else if (equalLettersIgnoringASCIICase(name, formAction)) setCSPDirective(name, value, m_formAction); - else if (equalIgnoringCase(name, pluginTypes)) + else if (equalLettersIgnoringASCIICase(name, pluginTypes)) setCSPDirective(name, value, m_pluginTypes); - else if (equalIgnoringCase(name, reflectedXSS)) + else if (equalLettersIgnoringASCIICase(name, reflectedXSS)) parseReflectedXSS(name, value); else m_policy->reportUnsupportedDirective(name); @@ -1677,36 +1690,27 @@ void ContentSecurityPolicy::reportViolation(const String& directiveText, const S void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const { - static NeverDestroyed allow(ASCIILiteral("allow")); - static NeverDestroyed options(ASCIILiteral("options")); - static NeverDestroyed policyURI(ASCIILiteral("policy-uri")); - static NeverDestroyed allowMessage(ASCIILiteral("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.")); - static NeverDestroyed optionsMessage(ASCIILiteral("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect.")); - static NeverDestroyed policyURIMessage(ASCIILiteral("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header.")); - String message; - if (equalIgnoringCase(name, allow)) - message = allowMessage; - else if (equalIgnoringCase(name, options)) - message = optionsMessage; - else if (equalIgnoringCase(name, policyURI)) - message = policyURIMessage; + if (equalLettersIgnoringASCIICase(name, "allow")) + message = ASCIILiteral("The 'allow' directive has been replaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."); + else if (equalLettersIgnoringASCIICase(name, "options")) + message = ASCIILiteral("The 'options' directive has been replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 'script-src' and 'style-src' directives. Please use those directives instead, as 'options' has no effect."); + else if (equalLettersIgnoringASCIICase(name, "policy-uri")) + message = ASCIILiteral("The 'policy-uri' directive has been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."); else - message = makeString("Unrecognized Content-Security-Policy directive '", name, "'.\n"); + message = makeString("Unrecognized Content-Security-Policy directive '", name, "'.\n"); // FIXME: Why does this include a newline? logToConsole(message); } void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& directiveName, const String& sourceExpression) const { - String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?"; - logToConsole(message); + logToConsole("The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?"); } void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const { - String message = makeString("Ignoring duplicate Content-Security-Policy directive '", name, "'.\n"); - logToConsole(message); + logToConsole(makeString("Ignoring duplicate Content-Security-Policy directive '", name, "'.\n")); } void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) const @@ -1752,7 +1756,7 @@ void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiveName, const String& source) const { String message = makeString("The source list for Content Security Policy directive '", directiveName, "' contains an invalid source: '", source, "'. It will be ignored."); - if (equalIgnoringCase(source, "'none'")) + if (equalLettersIgnoringASCIICase(source, "'none'")) message = makeString(message, " Note that 'none' has no effect unless it is the only expression in the source list."); logToConsole(message); } diff --git a/Source/WebCore/platform/URL.cpp b/Source/WebCore/platform/URL.cpp index 788e8fd2bb9f..f2f3569b4af9 100644 --- a/Source/WebCore/platform/URL.cpp +++ b/Source/WebCore/platform/URL.cpp @@ -518,7 +518,7 @@ void URL::init(const URL& base, const String& relative, const TextEncoding& enco ++p; } if (*p == ':') { - if (p[1] != '/' && equalIgnoringCase(base.protocol(), String(str, p - str)) && base.isHierarchical()) + if (p[1] != '/' && equalIgnoringASCIICase(base.protocol(), StringView(reinterpret_cast(str), p - str)) && base.isHierarchical()) str = p + 1; else absolute = true; diff --git a/Source/WebCore/platform/cocoa/ContentFilterUnblockHandlerCocoa.mm b/Source/WebCore/platform/cocoa/ContentFilterUnblockHandlerCocoa.mm index b7acbab48b0f..1114bd6fbded 100644 --- a/Source/WebCore/platform/cocoa/ContentFilterUnblockHandlerCocoa.mm +++ b/Source/WebCore/platform/cocoa/ContentFilterUnblockHandlerCocoa.mm @@ -133,7 +133,7 @@ #endif } - bool isUnblockRequest = request.url().protocolIs(ContentFilter::urlScheme()) && equalIgnoringCase(request.url().host(), m_unblockURLHost); + bool isUnblockRequest = request.url().protocolIs(ContentFilter::urlScheme()) && equalIgnoringASCIICase(request.url().host(), m_unblockURLHost); #if !LOG_DISABLED if (isUnblockRequest) LOG(ContentFiltering, "ContentFilterUnblockHandler will handle <%s> as an unblock request.\n", request.url().string().ascii().data()); diff --git a/Source/WebCore/platform/efl/PlatformSpeechSynthesisProviderEfl.cpp b/Source/WebCore/platform/efl/PlatformSpeechSynthesisProviderEfl.cpp index 015a3928f0cc..82d11a63f4ed 100644 --- a/Source/WebCore/platform/efl/PlatformSpeechSynthesisProviderEfl.cpp +++ b/Source/WebCore/platform/efl/PlatformSpeechSynthesisProviderEfl.cpp @@ -74,9 +74,7 @@ String PlatformSpeechSynthesisProviderEfl::voiceName(PassRefPtr>& voiceList = m_platformSpeechSynthesizer->voiceList(); for (const auto& voice : voiceList) { // Espeak adds an empty character at the beginning of the language - unsigned length = voice->lang().length(); - String lang = voice->lang().substring(1, length); - if (equalIgnoringCase(language, lang)) + if (equalIgnoringASCIICase(StringView(voice->lang()).substring(1), language)) return voice->name(); } } diff --git a/Source/WebCore/platform/graphics/FontCache.cpp b/Source/WebCore/platform/graphics/FontCache.cpp index f58debd334a8..4af09164bb50 100644 --- a/Source/WebCore/platform/graphics/FontCache.cpp +++ b/Source/WebCore/platform/graphics/FontCache.cpp @@ -113,7 +113,13 @@ struct FontPlatformDataCacheKey { bool operator==(const FontPlatformDataCacheKey& other) const { - return equalIgnoringCase(m_family, other.m_family) && m_fontDescriptionKey == other.m_fontDescriptionKey; + if (m_fontDescriptionKey != other.m_fontDescriptionKey) + return false; + if (m_family.impl() == other.m_family.impl()) + return true; + if (m_family.isNull() || other.m_family.isNull()) + return false; + return CaseFoldingHash::equal(m_family, other.m_family); } FontDescriptionKey m_fontDescriptionKey; @@ -142,72 +148,60 @@ static FontPlatformDataCache& fontPlatformDataCache() return cache; } -static bool familyNameEqualIgnoringCase(const AtomicString& familyName, const char* reference, unsigned length) +static AtomicString alternateFamilyName(const AtomicString& familyName) { - ASSERT(length > 0); - ASSERT(familyName.length() == length); - ASSERT(strlen(reference) == length); - const AtomicStringImpl* familyNameImpl = familyName.impl(); - if (familyNameImpl->is8Bit()) - return equalIgnoringCase(familyNameImpl->characters8(), reinterpret_cast(reference), length); - return equalIgnoringCase(familyNameImpl->characters16(), reinterpret_cast(reference), length); -} - -template -static inline bool familyNameEqualIgnoringCase(const AtomicString& familyName, const char (&reference)[length]) -{ - return familyNameEqualIgnoringCase(familyName, reference, length - 1); -} - -static const AtomicString alternateFamilyName(const AtomicString& familyName) -{ - // Alias Courier and Courier New. - // Alias Times and Times New Roman. - // Alias Arial and Helvetica. switch (familyName.length()) { case 5: - if (familyNameEqualIgnoringCase(familyName, "Arial")) + if (equalLettersIgnoringASCIICase(familyName, "arial")) return AtomicString("Helvetica", AtomicString::ConstructFromLiteral); - if (familyNameEqualIgnoringCase(familyName, "Times")) + if (equalLettersIgnoringASCIICase(familyName, "times")) return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral); break; case 7: - if (familyNameEqualIgnoringCase(familyName, "Courier")) + if (equalLettersIgnoringASCIICase(familyName, "courier")) return AtomicString("Courier New", AtomicString::ConstructFromLiteral); break; +#if OS(WINDOWS) + // On Windows, we don't support bitmap fonts, but legacy content expects support. + // Thus we allow Times New Roman as an alternative for the bitmap font MS Serif, + // even if the webpage does not specify fallback. + // FIXME: Seems unlikely this is still needed. If it was really needed, I think we + // would need it on other platforms too. + case 8: + if (equalLettersIgnoringASCIICase(familyName, "ms serif")) + return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral); + break; +#endif case 9: - if (familyNameEqualIgnoringCase(familyName, "Helvetica")) + if (equalLettersIgnoringASCIICase(familyName, "helvetica")) return AtomicString("Arial", AtomicString::ConstructFromLiteral); break; #if !OS(WINDOWS) - // On Windows, Courier New (truetype font) is always present and - // Courier is a bitmap font. So, we don't want to map Courier New to - // Courier. + // On Windows, Courier New is a TrueType font that is always present and + // Courier is a bitmap font that we do not support. So, we don't want to map + // Courier New to Courier. + // FIXME: Not sure why this is harmful on Windows, since the alternative will + // only be tried if Courier New is not found. case 11: - if (familyNameEqualIgnoringCase(familyName, "Courier New")) + if (equalLettersIgnoringASCIICase(familyName, "courier new")) return AtomicString("Courier", AtomicString::ConstructFromLiteral); break; -#endif // !OS(WINDOWS) - case 15: - if (familyNameEqualIgnoringCase(familyName, "Times New Roman")) - return AtomicString("Times", AtomicString::ConstructFromLiteral); - break; +#endif #if OS(WINDOWS) - // On Windows, bitmap fonts are blocked altogether so that we have to - // alias MS Sans Serif (bitmap font) -> Microsoft Sans Serif (truetype font) + // On Windows, we don't support bitmap fonts, but legacy content expects support. + // Thus we allow Microsoft Sans Serif as an alternative for the bitmap font MS Sans Serif, + // even if the webpage does not specify fallback. + // FIXME: Seems unlikely this is still needed. If it was really needed, I think we + // would need it on other platforms too. case 13: - if (familyNameEqualIgnoringCase(familyName, "MS Sans Serif")) + if (equalLettersIgnoringASCIICase(familyName, "ms sans serif")) return AtomicString("Microsoft Sans Serif", AtomicString::ConstructFromLiteral); break; - - // Alias MS Serif (bitmap) -> Times New Roman (truetype font). There's no - // 'Microsoft Sans Serif-equivalent' for Serif. - case 8: - if (familyNameEqualIgnoringCase(familyName, "MS Serif")) - return AtomicString("Times New Roman", AtomicString::ConstructFromLiteral); +#endif + case 15: + if (equalLettersIgnoringASCIICase(familyName, "times new roman")) + return AtomicString("Times", AtomicString::ConstructFromLiteral); break; -#endif // OS(WINDOWS) - } return nullAtom; diff --git a/Source/WebCore/platform/graphics/FontCascade.cpp b/Source/WebCore/platform/graphics/FontCascade.cpp index c7102e99226a..16dfd674244e 100644 --- a/Source/WebCore/platform/graphics/FontCascade.cpp +++ b/Source/WebCore/platform/graphics/FontCascade.cpp @@ -201,7 +201,11 @@ static bool operator==(const FontCascadeCacheKey& a, const FontCascadeCacheKey& if (a.families.size() != b.families.size()) return false; for (unsigned i = 0; i < a.families.size(); ++i) { - if (!equalIgnoringCase(a.families[i].impl(), b.families[i].impl())) + auto* aImpl = a.families[i].impl(); + auto* bImpl = b.families[i].impl(); + if (aImpl == bImpl) + continue; + if (!aImpl || !bImpl || !CaseFoldingHash::equal(aImpl, bImpl)) return false; } return true; diff --git a/Source/WebCore/platform/graphics/FontDescription.cpp b/Source/WebCore/platform/graphics/FontDescription.cpp index 5586ddbbabcb..1660c43118f6 100644 --- a/Source/WebCore/platform/graphics/FontDescription.cpp +++ b/Source/WebCore/platform/graphics/FontDescription.cpp @@ -142,6 +142,7 @@ FontWeight FontCascadeDescription::bolderWeight(void) const } #if ENABLE(IOS_TEXT_AUTOSIZING) + bool FontCascadeDescription::familiesEqualForTextAutoSizing(const FontCascadeDescription& other) const { unsigned thisFamilyCount = familyCount(); @@ -151,12 +152,13 @@ bool FontCascadeDescription::familiesEqualForTextAutoSizing(const FontCascadeDes return false; for (unsigned i = 0; i < thisFamilyCount; ++i) { - if (!equalIgnoringCase(familyAt(i), other.familyAt(i))) + if (!equalIgnoringASCIICase(familyAt(i), other.familyAt(i))) return false; } return true; } + #endif // ENABLE(IOS_TEXT_AUTOSIZING) } // namespace WebCore diff --git a/Source/WebCore/platform/graphics/MediaPlayer.cpp b/Source/WebCore/platform/graphics/MediaPlayer.cpp index 5ef29f57810a..579f45969b66 100644 --- a/Source/WebCore/platform/graphics/MediaPlayer.cpp +++ b/Source/WebCore/platform/graphics/MediaPlayer.cpp @@ -854,7 +854,7 @@ MediaPlayer::SupportsType MediaPlayer::supportsType(const MediaEngineSupportPara // slow connections. if (client && client->mediaPlayerNeedsSiteSpecificHacks()) { String host = client->mediaPlayerDocumentHost(); - if ((host.endsWith(".youtube.com", false) || equalIgnoringCase("youtube.com", host)) + if ((host.endsWith(".youtube.com", false) || equalLettersIgnoringASCIICase(host, "youtube.com")) && (parameters.type.startsWith("video/webm", false) || parameters.type.startsWith("video/x-flv", false))) return IsNotSupported; } diff --git a/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp b/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp index 8a3565450363..c106baf089a1 100644 --- a/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp +++ b/Source/WebCore/platform/graphics/avfoundation/cf/MediaPlayerPrivateAVFoundationCF.cpp @@ -873,12 +873,13 @@ void MediaPlayerPrivateAVFoundationCF::paint(GraphicsContext& context, const Flo } #if HAVE(AVFOUNDATION_LOADER_DELEGATE) && ENABLE(ENCRYPTED_MEDIA_V2) + static bool keySystemIsSupported(const String& keySystem) { - if (equalIgnoringCase(keySystem, "com.apple.fps") || equalIgnoringCase(keySystem, "com.apple.fps.1_0")) - return true; - return false; + return equalLettersIgnoringASCIICase(keySystem, "com.apple.fps") + || equalLettersIgnoringASCIICase(keySystem, "com.apple.fps.1_0"); } + #endif static const HashSet& avfMIMETypes() diff --git a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp index 50f0f9ba9aaf..a29020239ba8 100644 --- a/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp @@ -316,6 +316,16 @@ static bool areStronglyAliased(const String& familyA, const String& familyB) return false; } +static inline bool isCommonlyUsedGenericFamily(const String& familyNameString) +{ + return equalLettersIgnoringASCIICase(familyNameString, "sans") + || equalLettersIgnoringASCIICase(familyNameString, "sans-serif") + || equalLettersIgnoringASCIICase(familyNameString, "serif") + || equalLettersIgnoringASCIICase(familyNameString, "monospace") + || equalLettersIgnoringASCIICase(familyNameString, "fantasy") + || equalLettersIgnoringASCIICase(familyNameString, "cursive"); +} + std::unique_ptr FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm) @@ -368,11 +378,7 @@ std::unique_ptr FontCache::createFontPlatformData(const FontDe // and allow WebCore to give us the next font on the CSS fallback list. The exceptions are if // this family name is a commonly-used generic family, or if the families are strongly-aliased. // Checking for a strong alias comes last, since it is slow. - if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching) - && !(equalIgnoringCase(familyNameString, "sans") || equalIgnoringCase(familyNameString, "sans-serif") - || equalIgnoringCase(familyNameString, "serif") || equalIgnoringCase(familyNameString, "monospace") - || equalIgnoringCase(familyNameString, "fantasy") || equalIgnoringCase(familyNameString, "cursive")) - && !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching)) + if (!equalIgnoringASCIICase(familyNameAfterConfiguration, familyNameAfterMatching) && !isCommonlyUsedGenericFamily(familyNameString) && !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching)) return nullptr; // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently diff --git a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp index 46d9471d618f..a1a189a2b037 100644 --- a/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp +++ b/Source/WebCore/platform/graphics/freetype/FontCustomPlatformDataFreeType.cpp @@ -89,7 +89,9 @@ std::unique_ptr createFontCustomPlatformData(SharedBuffe bool FontCustomPlatformData::supportsFormat(const String& format) { - return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff"); + return equalLettersIgnoringASCIICase(format, "truetype") + || equalLettersIgnoringASCIICase(format, "opentype") + || equalLettersIgnoringASCIICase(format, "woff"); } } diff --git a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp index 8810d318d269..c94f37e30168 100644 --- a/Source/WebCore/platform/graphics/win/FontCacheWin.cpp +++ b/Source/WebCore/platform/graphics/win/FontCacheWin.cpp @@ -403,8 +403,7 @@ static inline bool isGDIFontWeightBold(LONG gdiFontWeight) static LONG adjustedGDIFontWeight(LONG gdiFontWeight, const String& family) { - static AtomicString lucidaStr("Lucida Grande"); - if (equalIgnoringCase(family, lucidaStr)) { + if (equalLettersIgnoringASCIICase(family, "lucida grande")) { if (gdiFontWeight == FW_NORMAL) return FW_MEDIUM; if (gdiFontWeight == FW_BOLD) @@ -563,10 +562,7 @@ Vector FontCache::getTraitsInFamily(const AtomicString& familyNa std::unique_ptr FontCache::createFontPlatformData(const FontDescription& fontDescription, const AtomicString& family) { - bool isLucidaGrande = false; - static AtomicString lucidaStr("Lucida Grande"); - if (equalIgnoringCase(family, lucidaStr)) - isLucidaGrande = true; + bool isLucidaGrande = equalLettersIgnoringASCIICase(family, "lucida grande"); bool useGDI = fontDescription.renderingMode() == FontRenderingMode::Alternate && !isLucidaGrande; diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp index 9732073211d4..7692daf1f1f5 100644 --- a/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp +++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformData.cpp @@ -96,7 +96,9 @@ std::unique_ptr createFontCustomPlatformData(SharedBuffe bool FontCustomPlatformData::supportsFormat(const String& format) { - return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff"); + return equalLettersIgnoringASCIICase(format, "truetype") + || equalLettersIgnoringASCIICase(format, "opentype") + || equalLettersIgnoringASCIICase(format, "woff"); } } diff --git a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp index 809700d0ba3e..44134280f9cc 100644 --- a/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp +++ b/Source/WebCore/platform/graphics/win/FontCustomPlatformDataCairo.cpp @@ -97,7 +97,9 @@ std::unique_ptr createFontCustomPlatformData(SharedBuffe bool FontCustomPlatformData::supportsFormat(const String& format) { - return equalIgnoringCase(format, "truetype") || equalIgnoringCase(format, "opentype") || equalIgnoringCase(format, "woff"); + return equalLettersIgnoringASCIICase(format, "truetype") + || equalLettersIgnoringASCIICase(format, "opentype") + || equalLettersIgnoringASCIICase(format, "woff"); } } diff --git a/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm b/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm index 868a8e2090d2..e2ebd1b7e8c6 100644 --- a/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm +++ b/Source/WebCore/platform/mac/PlatformSpeechSynthesizerMac.mm @@ -97,16 +97,14 @@ - (void)speakUtterance:(WebCore::PlatformSpeechSynthesisUtterance *)utterance // Find if we should use a specific voice based on the voiceURI in utterance. // Otherwise, find the voice that matches the language. The Mac doesn't have a default voice per language, so the first // one will have to do. - Vector> voiceList = m_synthesizerObject->voiceList(); - size_t voiceListSize = voiceList.size(); WebCore::PlatformSpeechSynthesisVoice* utteranceVoice = utterance->voice(); // If no voice was specified, try to match by language. if (!utteranceVoice && !utterance->lang().isEmpty()) { - for (size_t k = 0; k < voiceListSize; k++) { - if (equalIgnoringCase(utterance->lang(), voiceList[k]->lang())) { - utteranceVoice = voiceList[k].get(); - if (voiceList[k]->isDefault()) + for (auto& voice : m_synthesizerObject->voiceList()) { + if (equalIgnoringASCIICase(utterance->lang(), voice->lang())) { + utteranceVoice = voice.get(); + if (voice->isDefault()) break; } } diff --git a/Source/WebCore/platform/network/CacheValidation.cpp b/Source/WebCore/platform/network/CacheValidation.cpp index 8126166eb831..f99c6b128d59 100644 --- a/Source/WebCore/platform/network/CacheValidation.cpp +++ b/Source/WebCore/platform/network/CacheValidation.cpp @@ -62,8 +62,8 @@ const char* const headerPrefixesToIgnoreAfterRevalidation[] = { static inline bool shouldUpdateHeaderAfterRevalidation(const String& header) { - for (size_t i = 0; i < WTF_ARRAY_LENGTH(headersToIgnoreAfterRevalidation); i++) { - if (equalIgnoringCase(header, headersToIgnoreAfterRevalidation[i])) + for (auto& headerToIgnore : headersToIgnoreAfterRevalidation) { + if (equalIgnoringASCIICase(header, headerToIgnore)) return false; } for (size_t i = 0; i < WTF_ARRAY_LENGTH(headerPrefixesToIgnoreAfterRevalidation); i++) { diff --git a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp index 77426fa8845b..4df0ea696eb2 100644 --- a/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp +++ b/Source/WebCore/platform/network/curl/ResourceHandleManager.cpp @@ -368,17 +368,17 @@ static bool isAppendableHeader(const String &key) "vary", "via", "warning", - "www-authenticate", - 0 + "www-authenticate" }; // Custom headers start with 'X-', and need no further checking. if (key.startsWith("x-", /* caseSensitive */ false)) return true; - for (unsigned i = 0; appendableHeaders[i]; ++i) - if (equalIgnoringCase(key, appendableHeaders[i])) + for (auto& header : appendableHeaders) { + if (equalIgnoringASCIICase(key, header)) return true; + } return false; } diff --git a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm index 79524a52c100..e5f3e641da85 100644 --- a/Source/WebCore/platform/network/mac/ResourceHandleMac.mm +++ b/Source/WebCore/platform/network/mac/ResourceHandleMac.mm @@ -436,7 +436,7 @@ static bool synchronousWillSendRequestEnabled() if (redirectResponse.httpStatusCode() == 307) { String lastHTTPMethod = d->m_lastHTTPMethod; - if (!equalIgnoringCase(lastHTTPMethod, request.httpMethod())) { + if (!equalIgnoringASCIICase(lastHTTPMethod, request.httpMethod())) { request.setHTTPMethod(lastHTTPMethod); FormData* body = d->m_firstRequest.httpBody(); diff --git a/Source/WebCore/platform/text/mac/LocaleMac.mm b/Source/WebCore/platform/text/mac/LocaleMac.mm index 4c9161cc30e4..f7166302581e 100644 --- a/Source/WebCore/platform/text/mac/LocaleMac.mm +++ b/Source/WebCore/platform/text/mac/LocaleMac.mm @@ -60,7 +60,7 @@ static inline String languageFromLocale(const String& locale) RetainPtr currentLocale = [NSLocale currentLocale]; String currentLocaleLanguage = languageFromLocale(String([currentLocale.get() localeIdentifier])); String localeLanguage = languageFromLocale(locale); - if (equalIgnoringCase(currentLocaleLanguage, localeLanguage)) + if (equalIgnoringASCIICase(currentLocaleLanguage, localeLanguage)) return currentLocale; // It seems initWithLocaleIdentifier accepts dash-separated locale identifier. return adoptNS([[NSLocale alloc] initWithLocaleIdentifier:locale]); diff --git a/Source/WebCore/platform/text/win/LocaleWin.cpp b/Source/WebCore/platform/text/win/LocaleWin.cpp index 140a8e9bfb12..eb170b7872cc 100644 --- a/Source/WebCore/platform/text/win/LocaleWin.cpp +++ b/Source/WebCore/platform/text/win/LocaleWin.cpp @@ -119,8 +119,7 @@ static LCID WINAPI convertLocaleNameToLCID(LPCWSTR name, DWORD) static LCID LCIDFromLocaleInternal(LCID userDefaultLCID, const String& userDefaultLanguageCode, LocaleNameToLCIDPtr localeNameToLCID, String& locale) { - String localeLanguageCode = extractLanguageCode(locale); - if (equalIgnoringCase(localeLanguageCode, userDefaultLanguageCode)) + if (equalLettersIgnoringASCIICase(extractLanguageCode(locale), userDefaultLanguageCode)) return userDefaultLCID; return localeNameToLCID(locale.charactersWithNullTermination().data(), 0); } diff --git a/Source/WebCore/svg/SVGToOTFFontConversion.cpp b/Source/WebCore/svg/SVGToOTFFontConversion.cpp index 2a277550e4a9..964f7b153906 100644 --- a/Source/WebCore/svg/SVGToOTFFontConversion.cpp +++ b/Source/WebCore/svg/SVGToOTFFontConversion.cpp @@ -818,7 +818,7 @@ void SVGToOTFFontConverter::appendArabicReplacementSubtable(size_t subtableRecor for (auto& pair : m_codepointsToIndicesMap) { for (auto glyphIndex : pair.value) { auto& glyph = m_glyphs[glyphIndex]; - if (glyph.glyphElement && equalIgnoringCase(glyph.glyphElement->fastGetAttribute(SVGNames::arabic_formAttr), arabicForm)) + if (glyph.glyphElement && equalIgnoringASCIICase(glyph.glyphElement->fastGetAttribute(SVGNames::arabic_formAttr), arabicForm)) arabicFinalReplacements.append(std::make_pair(pair.value[0], glyphIndex)); } } diff --git a/Source/WebCore/xml/XMLHttpRequest.cpp b/Source/WebCore/xml/XMLHttpRequest.cpp index 570bbdc578b5..f03400711e4b 100644 --- a/Source/WebCore/xml/XMLHttpRequest.cpp +++ b/Source/WebCore/xml/XMLHttpRequest.cpp @@ -405,7 +405,7 @@ String XMLHttpRequest::uppercaseKnownHTTPMethod(const String& method) { const char* const methods[] = { "DELETE", "GET", "HEAD", "OPTIONS", "POST", "PUT" }; for (auto* value : methods) { - if (equalIgnoringCase(method, value)) { + if (equalIgnoringASCIICase(method, value)) { // Don't bother allocating a new string if it's already all uppercase. if (method == value) break; diff --git a/Source/WebCore/xml/XPathFunctions.cpp b/Source/WebCore/xml/XPathFunctions.cpp index d6821de1b735..a66c47191abe 100644 --- a/Source/WebCore/xml/XPathFunctions.cpp +++ b/Source/WebCore/xml/XPathFunctions.cpp @@ -596,7 +596,7 @@ Value FunLang::evaluate() const String langValue = languageAttribute->value(); while (true) { - if (equalIgnoringCase(langValue, lang)) + if (equalIgnoringASCIICase(langValue, lang)) return true; // Remove suffixes one by one. diff --git a/Source/WebCore/xml/XPathStep.cpp b/Source/WebCore/xml/XPathStep.cpp index 88958d25a898..0ae3403607cf 100644 --- a/Source/WebCore/xml/XPathStep.cpp +++ b/Source/WebCore/xml/XPathStep.cpp @@ -204,7 +204,7 @@ inline bool nodeMatchesBasicTest(Node& node, Step::Axis axis, const Step::NodeTe if (is(node.document())) { if (is(node)) { // Paths without namespaces should match HTML elements in HTML documents despite those having an XHTML namespace. Names are compared case-insensitively. - return equalIgnoringCase(downcast(node).localName(), name) && (namespaceURI.isNull() || namespaceURI == node.namespaceURI()); + return equalIgnoringASCIICase(downcast(node).localName(), name) && (namespaceURI.isNull() || namespaceURI == node.namespaceURI()); } // An expression without any prefix shouldn't match no-namespace nodes (because HTML5 says so). return downcast(node).hasLocalName(name) && namespaceURI == node.namespaceURI() && !namespaceURI.isNull(); diff --git a/Source/WebKit/mac/ChangeLog b/Source/WebKit/mac/ChangeLog index 4c52ba4e743c..3ee1d0b67bf4 100644 --- a/Source/WebKit/mac/ChangeLog +++ b/Source/WebKit/mac/ChangeLog @@ -1,3 +1,14 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * WebCoreSupport/WebFrameLoaderClient.mm: + (parameterValue): Use equalIgnoringASCIICase. No behavior change because the + only name we ever search for with this is "pluginspage". + 2016-01-27 Enrica Casucci Cache results of data detection in the UI process when load completes. diff --git a/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm b/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm index 19bc54b7389b..b9174db1382f 100644 --- a/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm +++ b/Source/WebKit/mac/WebCoreSupport/WebFrameLoaderClient.mm @@ -1726,12 +1726,12 @@ static BOOL shouldTryAppLink(WebView *webView, const NavigationAction& action, F return array; } -static String parameterValue(const Vector& paramNames, const Vector& paramValues, const String& name) +static String parameterValue(const Vector& paramNames, const Vector& paramValues, const char* name) { size_t size = paramNames.size(); ASSERT(size == paramValues.size()); for (size_t i = 0; i < size; ++i) { - if (equalIgnoringCase(paramNames[i], name)) + if (equalIgnoringASCIICase(paramNames[i], name)) return paramValues[i]; } return String(); diff --git a/Source/WebKit/win/ChangeLog b/Source/WebKit/win/ChangeLog index 025bdf248548..48f8ff21e2ef 100644 --- a/Source/WebKit/win/ChangeLog +++ b/Source/WebKit/win/ChangeLog @@ -1,3 +1,27 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * Plugins/PluginDatabase.cpp: + (WebCore::PluginDatabase::MIMETypeForExtension): Use equalIgnoringASCIICase to compare + file extensions. + * Plugins/PluginDatabaseWin.cpp: + (WebCore::PluginDatabase::getPluginPathsInDirectories): Use equalLettersIgnoringASCIICase + to compare filenames. + * Plugins/PluginPackageWin.cpp: + (WebCore::PluginPackage::isPluginBlacklisted): Use equalLettersIgnoringASCIICase to + compare DLL filenames. + * Plugins/PluginStream.cpp: + (WebCore::PluginStream::destroyStream): Use equalLettersIgnoringASCIICase to check HTTP method. + * Plugins/PluginView.cpp: + (WebCore::PluginView::setParameters): Use equalLettersIgnoringASCIICase to check + plug-in parameter name. + * WebView.cpp: + (WebView::canHandleRequest): Use URL::protocolIs instead of equalIgnoringCase. + 2016-01-22 Ryosuke Niwa document.createElement should be able to create a custom element diff --git a/Source/WebKit/win/Plugins/PluginDatabase.cpp b/Source/WebKit/win/Plugins/PluginDatabase.cpp index 0ee013d8433a..1a0c7e83b821 100644 --- a/Source/WebKit/win/Plugins/PluginDatabase.cpp +++ b/Source/WebKit/win/Plugins/PluginDatabase.cpp @@ -248,7 +248,7 @@ String PluginDatabase::MIMETypeForExtension(const String& extension) const const Vector& extensions = mime_it->value; bool foundMapping = false; for (unsigned i = 0; i < extensions.size(); i++) { - if (equalIgnoringCase(extensions[i], extension)) { + if (equalIgnoringASCIICase(extensions[i], extension)) { PluginPackage* plugin = (*it).get(); if (preferredPlugin && PluginPackage::equal(*plugin, *preferredPlugin)) diff --git a/Source/WebKit/win/Plugins/PluginDatabaseWin.cpp b/Source/WebKit/win/Plugins/PluginDatabaseWin.cpp index cdc6cf3499fc..62516bb93e13 100644 --- a/Source/WebKit/win/Plugins/PluginDatabaseWin.cpp +++ b/Source/WebKit/win/Plugins/PluginDatabaseWin.cpp @@ -94,7 +94,7 @@ void PluginDatabase::getPluginPathsInDirectories(HashSet& paths) const String filename = String(findFileData.cFileName, wcslen(findFileData.cFileName)); if ((!filename.startsWith("np", false) || !filename.endsWith("dll", false)) && - (!equalIgnoringCase(filename, "Plugin.dll") || !it->endsWith("Shockwave 10", false))) + (!equalLettersIgnoringASCIICase(filename, "plugin.dll") || !it->endsWith("Shockwave 10", false))) continue; String fullPath = *it + "\\" + filename; @@ -103,9 +103,9 @@ void PluginDatabase::getPluginPathsInDirectories(HashSet& paths) const paths.add(fullPath); - if (equalIgnoringCase(filename, "npdsplay.dll")) + if (equalLettersIgnoringASCIICase(filename, "npdsplay.dll")) oldWMPPluginPath = fullPath; - else if (equalIgnoringCase(filename, "np-mswmp.dll")) + else if (equalLettersIgnoringASCIICase(filename, "np-mswmp.dll")) newWMPPluginPath = fullPath; } while (FindNextFileW(hFind, &findFileData) != 0); diff --git a/Source/WebKit/win/Plugins/PluginPackageWin.cpp b/Source/WebKit/win/Plugins/PluginPackageWin.cpp index a85257d62292..c2bbcc450598 100644 --- a/Source/WebKit/win/Plugins/PluginPackageWin.cpp +++ b/Source/WebKit/win/Plugins/PluginPackageWin.cpp @@ -71,10 +71,10 @@ bool PluginPackage::isPluginBlacklisted() if (compareFileVersion(slPluginMinRequired) < 0) return true; - } else if (equalIgnoringCase(fileName(), "npmozax.dll")) { + } else if (equalLettersIgnoringASCIICase(fileName(), "npmozax.dll")) { // Bug 15217: Mozilla ActiveX control complains about missing xpcom_core.dll return true; - } else if (equalIgnoringCase(fileName(), "npwpf.dll")) { + } else if (equalLettersIgnoringASCIICase(fileName(), "npwpf.dll")) { // Bug 57119: Microsoft Windows Presentation Foundation (WPF) plug-in complains about missing xpcom.dll return true; } else if (name() == "Yahoo Application State Plugin") { diff --git a/Source/WebKit/win/Plugins/PluginStream.cpp b/Source/WebKit/win/Plugins/PluginStream.cpp index e979598493ff..d2b5c913198c 100644 --- a/Source/WebKit/win/Plugins/PluginStream.cpp +++ b/Source/WebKit/win/Plugins/PluginStream.cpp @@ -294,7 +294,7 @@ void PluginStream::destroyStream() if (m_loader) m_loader->setDefersLoading(true); if (!newStreamCalled && m_quirks.contains(PluginQuirkFlashURLNotifyBug) && - equalIgnoringCase(m_resourceRequest.httpMethod(), "POST")) { + equalLettersIgnoringASCIICase(m_resourceRequest.httpMethod(), "post")) { m_transferMode = NP_NORMAL; m_stream.url = ""; m_stream.notifyData = m_notifyData; diff --git a/Source/WebKit/win/Plugins/PluginView.cpp b/Source/WebKit/win/Plugins/PluginView.cpp index 98542eba4d1d..b3344aafc0d6 100644 --- a/Source/WebKit/win/Plugins/PluginView.cpp +++ b/Source/WebKit/win/Plugins/PluginView.cpp @@ -715,7 +715,7 @@ void PluginView::setParameters(const Vector& paramNames, const Vector(fastMalloc(sizeof(char*) * size)); for (unsigned i = 0; i < size; i++) { - if (m_plugin->quirks().contains(PluginQuirkRemoveWindowlessVideoParam) && equalIgnoringCase(paramNames[i], "windowlessvideo")) + if (m_plugin->quirks().contains(PluginQuirkRemoveWindowlessVideoParam) && equalLettersIgnoringASCIICase(paramNames[i], "windowlessvideo")) continue; if (paramNames[i] == "pluginspage") diff --git a/Source/WebKit/win/WebView.cpp b/Source/WebKit/win/WebView.cpp index 03b441316630..425d0a4c74c9 100644 --- a/Source/WebKit/win/WebView.cpp +++ b/Source/WebKit/win/WebView.cpp @@ -1365,16 +1365,12 @@ void WebView::closeWindow() bool WebView::canHandleRequest(const WebCore::ResourceRequest& request) { - // On the mac there's an about url protocol implementation but CFNetwork doesn't have that. - if (equalIgnoringCase(String(request.url().protocol()), "about")) - return true; - #if USE(CFNETWORK) - if (CFURLProtocolCanHandleRequest(request.cfURLRequest(UpdateHTTPBody))) + // On the Mac there's an about URL protocol implementation but Windows CFNetwork doesn't have that. + if (request.url().protocolIs("about")) return true; - // FIXME: Mac WebKit calls _representationExistsForURLScheme here - return false; + return CFURLProtocolCanHandleRequest(request.cfURLRequest(UpdateHTTPBody)); #else return true; #endif diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog index 572dac9fb914..0edea49af253 100644 --- a/Source/WebKit2/ChangeLog +++ b/Source/WebKit2/ChangeLog @@ -1,3 +1,23 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * Shared/API/c/WKString.cpp: + (WKStringIsEqualToUTF8CStringIgnoringCase): Use equalIgnoringASCIICase. + This is a change in behavior for callers who passed non-ASCII letters to + this function and expected case insensitive comparison. + + * WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm: + (WebKit::PDFPlugin::streamDidReceiveResponse): Use equalIgnoringASCIICase. + No change in behavior because this is just checking a fixed ASCII MIME type. + (WebKit::PDFPlugin::manualStreamDidReceiveResponse): Ditto. + * WebProcess/Plugins/PDF/PDFPlugin.mm: + (WebKit::PDFPlugin::streamDidReceiveResponse): Ditto. + (WebKit::PDFPlugin::manualStreamDidReceiveResponse): Ditto. + 2016-01-27 Alex Christensen Fix CMake build after r195722. diff --git a/Source/WebKit2/Shared/API/c/WKString.cpp b/Source/WebKit2/Shared/API/c/WKString.cpp index 49adbf9af756..305dd01b53a1 100644 --- a/Source/WebKit2/Shared/API/c/WKString.cpp +++ b/Source/WebKit2/Shared/API/c/WKString.cpp @@ -102,13 +102,16 @@ bool WKStringIsEqual(WKStringRef aRef, WKStringRef bRef) bool WKStringIsEqualToUTF8CString(WKStringRef aRef, const char* b) { + // FIXME: Should we add a fast path that avoids memory allocation when the string is all ASCII? + // FIXME: We can do even the general case more efficiently if we write a function in StringView that understands UTF-8 C strings. return toImpl(aRef)->stringView() == WTF::String::fromUTF8(b); } bool WKStringIsEqualToUTF8CStringIgnoringCase(WKStringRef aRef, const char* b) { - // FIXME: Instead of copying the string here, we should add a version of equalIgnoringCase that takes StringViews. - return equalIgnoringCase(toImpl(aRef)->string(), WTF::String::fromUTF8(b)); + // FIXME: Should we add a fast path that avoids memory allocation when the string is all ASCII? + // FIXME: We can do even the general case more efficiently if we write a function in StringView that understands UTF-8 C strings. + return equalIgnoringASCIICase(toImpl(aRef)->stringView(), WTF::String::fromUTF8(b)); } WKStringRef WKStringCreateWithJSString(JSStringRef jsStringRef) diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm index 551ef191a430..4bebbe4e945e 100644 --- a/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm +++ b/Source/WebKit2/WebProcess/Plugins/PDF/DeprecatedPDFPlugin.mm @@ -944,7 +944,7 @@ static void jsPDFDocFinalize(JSObjectRef object) m_suggestedFilename = suggestedFilename; - if (equalIgnoringCase(mimeType, postScriptMIMEType)) + if (equalIgnoringASCIICase(mimeType, postScriptMIMEType)) m_isPostScript = true; } @@ -977,7 +977,7 @@ static void jsPDFDocFinalize(JSObjectRef object) { m_suggestedFilename = suggestedFilename; - if (equalIgnoringCase(mimeType, postScriptMIMEType)) + if (equalIgnoringASCIICase(mimeType, postScriptMIMEType)) m_isPostScript = true; } diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm index bb6d5ed77af4..af19f31c0850 100644 --- a/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm +++ b/Source/WebKit2/WebProcess/Plugins/PDF/PDFPlugin.mm @@ -695,7 +695,7 @@ static void jsPDFDocFinalize(JSObjectRef object) m_suggestedFilename = suggestedFilename; - if (equalIgnoringCase(mimeType, postScriptMIMEType)) + if (equalIgnoringASCIICase(mimeType, postScriptMIMEType)) m_isPostScript = true; } @@ -728,7 +728,7 @@ static void jsPDFDocFinalize(JSObjectRef object) { m_suggestedFilename = suggestedFilename; - if (equalIgnoringCase(mimeType, postScriptMIMEType)) + if (equalIgnoringASCIICase(mimeType, postScriptMIMEType)) m_isPostScript = true; } diff --git a/Tools/ChangeLog b/Tools/ChangeLog index d6b35fe2ab87..c8b39f09c974 100644 --- a/Tools/ChangeLog +++ b/Tools/ChangeLog @@ -1,3 +1,23 @@ +2016-01-28 Darin Adler + + Remove equalIgnoringCase since all callers really wanted equalIgnoringASCIICase + https://bugs.webkit.org/show_bug.cgi?id=153411 + + Reviewed by Ryosuke Niwa. + + * Scripts/do-webcore-rename: Removed rename of equalIgnoringCase since we + have removed the function instead. + + * TestWebKitAPI/Tests/WTF/StringImpl.cpp: + (TestWebKitAPI::TEST): Updated test since nullptr is now ambiguous since we + added overloads for const char*. + + * WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp: + (WTR::AccessibilityUIElement::isPressActionSupported): Use equalLettersIgnoringASCIICase. + (WTR::AccessibilityUIElement::hasPopup): Ditto. + * WebKitTestRunner/cocoa/CrashReporterInfo.mm: + (WTR::testPathFromURL): Ditto. + 2016-01-28 Konstantin Tokarev [webkitdirs] Clarify logic behind is{PortName} functions. diff --git a/Tools/Scripts/do-webcore-rename b/Tools/Scripts/do-webcore-rename index c830e22b7f4d..f0ccb21eac44 100755 --- a/Tools/Scripts/do-webcore-rename +++ b/Tools/Scripts/do-webcore-rename @@ -128,8 +128,6 @@ my %renamesContemplatedForTheFuture = ( "runtime_object" => "BridgedObject", "objc_runtime" => "ObjCBridge", - "equalIgnoringCase" => "equalFoldingCase", - "WTF_UNICODE_H" => "Unicode_h", "WTF_UNICODE_ICU_H" => "UnicodeICU_h", "UnicodeIcu" => "UnicodeICU", diff --git a/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp b/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp index 75fadf8c437a..01f36f7b6003 100644 --- a/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp +++ b/Tools/TestWebKitAPI/Tests/WTF/StringImpl.cpp @@ -140,9 +140,10 @@ TEST(WTF, StringImplEqualIgnoringASCIICaseBasic) TEST(WTF, StringImplEqualIgnoringASCIICaseWithNull) { RefPtr reference = StringImpl::createFromLiteral("aBcDeFG"); - ASSERT_FALSE(equalIgnoringASCIICase(nullptr, reference.get())); - ASSERT_FALSE(equalIgnoringASCIICase(reference.get(), nullptr)); - ASSERT_TRUE(equalIgnoringASCIICase(nullptr, nullptr)); + StringImpl* nullStringImpl = nullptr; + ASSERT_FALSE(equalIgnoringASCIICase(nullStringImpl, reference.get())); + ASSERT_FALSE(equalIgnoringASCIICase(reference.get(), nullStringImpl)); + ASSERT_TRUE(equalIgnoringASCIICase(nullStringImpl, nullStringImpl)); } TEST(WTF, StringImplEqualIgnoringASCIICaseWithEmpty) diff --git a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp index e7db2c962b51..1c873c93bb4c 100644 --- a/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp +++ b/Tools/WebKitTestRunner/InjectedBundle/atk/AccessibilityUIElementAtk.cpp @@ -317,17 +317,17 @@ const gchar* roleToString(AtkObject* object) #if ATK_CHECK_VERSION(2, 11, 3) if (role == ATK_ROLE_LANDMARK) { String xmlRolesValue = getAttributeSetValueForId(object, ObjectAttributeType, "xml-roles"); - if (equalIgnoringCase(xmlRolesValue, "banner")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "banner")) return landmarkStringBanner; - if (equalIgnoringCase(xmlRolesValue, "complementary")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "complementary")) return landmarkStringComplementary; - if (equalIgnoringCase(xmlRolesValue, "contentinfo")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "contentinfo")) return landmarkStringContentinfo; - if (equalIgnoringCase(xmlRolesValue, "main")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "main")) return landmarkStringMain; - if (equalIgnoringCase(xmlRolesValue, "navigation")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "navigation")) return landmarkStringNavigation; - if (equalIgnoringCase(xmlRolesValue, "search")) + if (equalLettersIgnoringASCIICase(xmlRolesValue, "search")) return landmarkStringSearch; } #endif @@ -1350,7 +1350,7 @@ bool AccessibilityUIElement::isPressActionSupported() return false; const gchar* actionName = atk_action_get_name(ATK_ACTION(m_element.get()), 0); - return equalIgnoringCase(actionName, String("press")) || equalIgnoringCase(actionName, String("jump")); + return equalLettersIgnoringASCIICase(actionName, "press") || equalLettersIgnoringASCIICase(actionName, "jump"); } bool AccessibilityUIElement::isIncrementActionSupported() @@ -1788,7 +1788,7 @@ bool AccessibilityUIElement::hasPopup() const return false; String hasPopupValue = getAttributeSetValueForId(ATK_OBJECT(m_element.get()), ObjectAttributeType, "haspopup"); - return equalIgnoringCase(hasPopupValue, "true"); + return equalLettersIgnoringASCIICase(hasPopupValue, "true"); } void AccessibilityUIElement::takeFocus() diff --git a/Tools/WebKitTestRunner/cocoa/CrashReporterInfo.mm b/Tools/WebKitTestRunner/cocoa/CrashReporterInfo.mm index 1dc4e2bcf06c..358ccd216919 100644 --- a/Tools/WebKitTestRunner/cocoa/CrashReporterInfo.mm +++ b/Tools/WebKitTestRunner/cocoa/CrashReporterInfo.mm @@ -45,7 +45,7 @@ static String testPathFromURL(WKURLRef url) String schemeString(schemeCFString.get()); String pathString(pathCFString.get()); - if (equalIgnoringCase(schemeString, "file")) { + if (equalLettersIgnoringASCIICase(schemeString, "file")) { String layoutTests("/LayoutTests/"); size_t layoutTestsOffset = pathString.find(layoutTests); if (layoutTestsOffset == notFound) @@ -54,7 +54,7 @@ static String testPathFromURL(WKURLRef url) return pathString.substring(layoutTestsOffset + layoutTests.length()); } - if (!equalIgnoringCase(schemeString, "http") && !equalIgnoringCase(schemeString, "https")) + if (!equalLettersIgnoringASCIICase(schemeString, "http") && !equalLettersIgnoringASCIICase(schemeString, "https")) return String(); RetainPtr hostCFString = adoptCF(CFURLCopyHostName(cfURL.get()));