Changeset 195501 in webkit


Ignore:
Timestamp:
Jan 22, 2016 6:04:41 PM (8 years ago)
Author:
rniwa@webkit.org
Message:

HTMLElement::nodeName should not upper case non-ASCII characters
https://bugs.webkit.org/show_bug.cgi?id=153231

Reviewed by Darin Adler.

LayoutTests/imported/w3c:

Rebaselined the test now that all test cases pass.

  • web-platform-tests/dom/nodes/Document-createElement-expected.txt:

Source/WebCore:

Use the newly added convertToASCIIUppercase to generate the string for tagName and nodeName.

Test: fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document.html

  • dom/QualifiedName.cpp:

(WebCore::QualifiedName::localNameUpper): Use convertToASCIIUppercase.

  • html/HTMLElement.cpp:

(WebCore::HTMLElement::nodeName): Use convertToASCIIUppercase.

Source/WTF:

Added convertToASCIIUppercase to AtomicString, String, and StringImpl.

  • wtf/text/AtomicString.cpp:

(WTF::AtomicString::convertASCIICase): Generalized from convertToASCIILowercase.
(WTF::AtomicString::convertToASCIILowercase):
(WTF::AtomicString::convertToASCIIUppercase):

  • wtf/text/AtomicString.h:
  • wtf/text/StringImpl.cpp:

(WTF::StringImpl::convertASCIICase): Generalized from convertToASCIILowercase.
(WTF::StringImpl::convertToASCIILowercase):
(WTF::StringImpl::convertToASCIIUppercase):

  • wtf/text/StringImpl.h:
  • wtf/text/WTFString.cpp:

(WTF::String::convertToASCIIUppercase): Added.

  • wtf/text/WTFString.h:

LayoutTests:

Added a regression test since the rebaselined W3C test case is very simple and doesn't all permutations.

  • fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document-expected.txt: Added.
  • fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document.html: Added.
Location:
trunk
Files:
2 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r195499 r195501  
     12016-01-20  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTMLElement::nodeName should not upper case non-ASCII characters
     4        https://bugs.webkit.org/show_bug.cgi?id=153231
     5
     6        Reviewed by Darin Adler.
     7
     8        Added a regression test since the rebaselined W3C test case is very simple and doesn't all permutations.
     9
     10        * fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document-expected.txt: Added.
     11        * fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document.html: Added.
     12
    1132016-01-22  Brady Eidson  <beidson@apple.com>
    214
  • trunk/LayoutTests/imported/w3c/ChangeLog

    r195497 r195501  
     12016-01-20  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTMLElement::nodeName should not upper case non-ASCII characters
     4        https://bugs.webkit.org/show_bug.cgi?id=153231
     5
     6        Reviewed by Darin Adler.
     7
     8        Rebaselined the test now that all test cases pass.
     9
     10        * web-platform-tests/dom/nodes/Document-createElement-expected.txt:
     11
    1122016-01-22  Chris Dumez  <cdumez@apple.com>
    213
  • trunk/LayoutTests/imported/w3c/web-platform-tests/dom/nodes/Document-createElement-expected.txt

    r195091 r195501  
    2222PASS createElement("marK")
    2323PASS createElement("İnput")
    24 FAIL createElement("ınput") assert_equals: expected "ıNPUT" but got "INPUT"
     24PASS createElement("ınput")
    2525PASS createElement("")
    2626PASS createElement("1foo")
  • trunk/Source/WTF/ChangeLog

    r195458 r195501  
     12016-01-20  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTMLElement::nodeName should not upper case non-ASCII characters
     4        https://bugs.webkit.org/show_bug.cgi?id=153231
     5
     6        Reviewed by Darin Adler.
     7
     8        Added convertToASCIIUppercase to AtomicString, String, and StringImpl.
     9
     10        * wtf/text/AtomicString.cpp:
     11        (WTF::AtomicString::convertASCIICase): Generalized from convertToASCIILowercase.
     12        (WTF::AtomicString::convertToASCIILowercase):
     13        (WTF::AtomicString::convertToASCIIUppercase):
     14        * wtf/text/AtomicString.h:
     15        * wtf/text/StringImpl.cpp:
     16        (WTF::StringImpl::convertASCIICase): Generalized from convertToASCIILowercase.
     17        (WTF::StringImpl::convertToASCIILowercase):
     18        (WTF::StringImpl::convertToASCIIUppercase):
     19        * wtf/text/StringImpl.h:
     20        * wtf/text/WTFString.cpp:
     21        (WTF::String::convertToASCIIUppercase): Added.
     22        * wtf/text/WTFString.h:
     23
    1242016-01-22  Chris Dumez  <cdumez@apple.com>
    225
  • trunk/Source/WTF/wtf/text/AtomicString.cpp

    r188169 r195501  
    4949}
    5050
    51 AtomicString AtomicString::convertToASCIILowercase() const
     51template<AtomicString::CaseConvertType type>
     52ALWAYS_INLINE AtomicString AtomicString::convertASCIICase() const
    5253{
    5354    StringImpl* impl = this->impl();
     
    6465        unsigned failingIndex;
    6566        for (unsigned i = 0; i < length; ++i) {
    66             if (UNLIKELY(isASCIIUpper(characters[i]))) {
     67            if (type == CaseConvertType::Lower ? UNLIKELY(isASCIIUpper(characters[i])) : LIKELY(isASCIILower(characters[i]))) {
    6768                failingIndex = i;
    6869                goto SlowPath;
     
    7576            localBuffer[i] = characters[i];
    7677        for (unsigned i = failingIndex; i < length; ++i)
    77             localBuffer[i] = toASCIILower(characters[i]);
     78            localBuffer[i] = type == CaseConvertType::Lower ? toASCIILower(characters[i]) : toASCIIUpper(characters[i]);
    7879        return AtomicString(localBuffer, length);
    7980    }
    8081
    81     RefPtr<StringImpl> convertedString = impl->convertToASCIILowercase();
    82     if (LIKELY(convertedString == impl))
     82    Ref<StringImpl> convertedString = type == CaseConvertType::Lower ? impl->convertToASCIILowercase() : impl->convertToASCIIUppercase();
     83    if (LIKELY(convertedString.ptr() == impl))
    8384        return *this;
    8485
    8586    AtomicString result;
    86     result.m_string = AtomicStringImpl::add(convertedString.get());
     87    result.m_string = AtomicStringImpl::add(convertedString.ptr());
    8788    return result;
     89}
     90
     91AtomicString AtomicString::convertToASCIILowercase() const
     92{
     93    return convertASCIICase<CaseConvertType::Lower>();
     94}
     95
     96AtomicString AtomicString::convertToASCIIUppercase() const
     97{
     98    return convertASCIICase<CaseConvertType::Upper>();
    8899}
    89100
  • trunk/Source/WTF/wtf/text/AtomicString.h

    r195452 r195501  
    155155
    156156    WTF_EXPORT_STRING_API AtomicString convertToASCIILowercase() const;
     157    WTF_EXPORT_STRING_API AtomicString convertToASCIIUppercase() const;
    157158    WTF_EXPORT_STRING_API AtomicString lower() const;
    158159    AtomicString upper() const { return AtomicString(impl()->upper()); }
     
    186187    // The explicit constructors with AtomicString::ConstructFromLiteral must be used for literals.
    187188    AtomicString(ASCIILiteral);
     189
     190    enum class CaseConvertType { Upper, Lower };
     191    template<CaseConvertType> AtomicString convertASCIICase() const;
    188192
    189193    WTF_EXPORT_STRING_API static AtomicString fromUTF8Internal(const char*, const char*);
  • trunk/Source/WTF/wtf/text/StringImpl.cpp

    r184867 r195501  
    680680}
    681681
     682template<StringImpl::CaseConvertType type, typename CharacterType>
     683ALWAYS_INLINE Ref<StringImpl> StringImpl::convertASCIICase(StringImpl& impl, const CharacterType* data, unsigned length)
     684{
     685    unsigned failingIndex;
     686    for (unsigned i = 0; i < length; ++i) {
     687        CharacterType character = data[i];
     688        if (type == CaseConvertType::Lower ? UNLIKELY(isASCIIUpper(character)) : LIKELY(isASCIILower(character))) {
     689            failingIndex = i;
     690            goto SlowPath;
     691        }
     692    }
     693    return impl;
     694
     695SlowPath:
     696    CharacterType* newData;
     697    Ref<StringImpl> newImpl = createUninitializedInternalNonEmpty(length, newData);
     698    for (unsigned i = 0; i < failingIndex; ++i)
     699        newData[i] = data[i];
     700    for (unsigned i = failingIndex; i < length; ++i)
     701        newData[i] = type == CaseConvertType::Lower ? toASCIILower(data[i]) : toASCIIUpper(data[i]);
     702    return newImpl;
     703}
     704
    682705Ref<StringImpl> StringImpl::convertToASCIILowercase()
    683706{
    684     if (is8Bit()) {
    685         unsigned failingIndex;
    686         for (unsigned i = 0; i < m_length; ++i) {
    687             LChar character = m_data8[i];
    688             if (UNLIKELY(isASCIIUpper(character))) {
    689                 failingIndex = i;
    690                 goto SlowPath;
    691             }
    692         }
    693         return *this;
    694 
    695 SlowPath:
    696         LChar* data8;
    697         Ref<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data8);
    698         for (unsigned i = 0; i < failingIndex; ++i)
    699             data8[i] = m_data8[i];
    700         for (unsigned i = failingIndex; i < m_length; ++i)
    701             data8[i] = toASCIILower(m_data8[i]);
    702         return newImpl;
    703     }
    704 
    705     bool noUpper = true;
    706     for (unsigned i = 0; i < m_length; ++i) {
    707         if (UNLIKELY(isASCIIUpper(m_data16[i])))
    708             noUpper = false;
    709     }
    710     if (noUpper)
    711         return *this;
    712 
    713     UChar* data16;
    714     Ref<StringImpl> newImpl = createUninitializedInternalNonEmpty(m_length, data16);
    715     for (unsigned i = 0; i < m_length; ++i)
    716         data16[i] = toASCIILower(m_data16[i]);
    717     return newImpl;
     707    if (is8Bit())
     708        return convertASCIICase<CaseConvertType::Lower>(*this, m_data8, m_length);
     709    return convertASCIICase<CaseConvertType::Lower>(*this, m_data16, m_length);
     710}
     711
     712Ref<StringImpl> StringImpl::convertToASCIIUppercase()
     713{
     714    if (is8Bit())
     715        return convertASCIICase<CaseConvertType::Upper>(*this, m_data8, m_length);
     716    return convertASCIICase<CaseConvertType::Upper>(*this, m_data16, m_length);
    718717}
    719718
  • trunk/Source/WTF/wtf/text/StringImpl.h

    r195452 r195501  
    677677
    678678    WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIILowercase();
     679    WTF_EXPORT_STRING_API Ref<StringImpl> convertToASCIIUppercase();
    679680    WTF_EXPORT_STRING_API Ref<StringImpl> lower();
    680681    WTF_EXPORT_STRING_API Ref<StringImpl> upper();
     
    852853    static const unsigned s_copyCharsInlineCutOff = 20;
    853854
     855    enum class CaseConvertType { Upper, Lower };
     856    template<CaseConvertType type, typename CharacterType> static Ref<StringImpl> convertASCIICase(StringImpl&, const CharacterType*, unsigned);
     857
    854858    BufferOwnership bufferOwnership() const { return static_cast<BufferOwnership>(m_hashAndFlags & s_hashMaskBufferOwnership); }
    855859    template <class UCharPredicate> Ref<StringImpl> stripMatchedCharacters(UCharPredicate);
  • trunk/Source/WTF/wtf/text/WTFString.cpp

    r194496 r195501  
    344344}
    345345
     346String String::convertToASCIIUppercase() const
     347{
     348    // FIXME: Should this function, and the many others like it, be inlined?
     349    if (!m_impl)
     350        return String();
     351    return m_impl->convertToASCIIUppercase();
     352}
     353
    346354String String::lower() const
    347355{
  • trunk/Source/WTF/wtf/text/WTFString.h

    r195458 r195501  
    340340    WTF_EXPORT_STRING_API String convertToASCIILowercase() const;
    341341    WTF_EXPORT_STRING_API String lower() const;
     342    WTF_EXPORT_STRING_API String convertToASCIIUppercase() const;
    342343    WTF_EXPORT_STRING_API String upper() const;
    343344
  • trunk/Source/WebCore/ChangeLog

    r195499 r195501  
     12016-01-20  Ryosuke Niwa  <rniwa@webkit.org>
     2
     3        HTMLElement::nodeName should not upper case non-ASCII characters
     4        https://bugs.webkit.org/show_bug.cgi?id=153231
     5
     6        Reviewed by Darin Adler.
     7
     8        Use the newly added convertToASCIIUppercase to generate the string for tagName and nodeName.
     9
     10        Test: fast/dom/Element/tagName-must-be-ASCII-uppercase-in-HTML-document.html
     11
     12        * dom/QualifiedName.cpp:
     13        (WebCore::QualifiedName::localNameUpper): Use convertToASCIIUppercase.
     14        * html/HTMLElement.cpp:
     15        (WebCore::HTMLElement::nodeName): Use convertToASCIIUppercase.
     16
    1172016-01-22  Brady Eidson  <beidson@apple.com>
    218
  • trunk/Source/WebCore/dom/QualifiedName.cpp

    r194819 r195501  
    124124{
    125125    if (!m_impl->m_localNameUpper)
    126         m_impl->m_localNameUpper = m_impl->m_localName.upper();
     126        m_impl->m_localNameUpper = m_impl->m_localName.convertToASCIIUppercase();
    127127    return m_impl->m_localNameUpper;
    128128}
  • trunk/Source/WebCore/html/HTMLElement.cpp

    r195452 r195501  
    7777    // ASCII characters that does not have to copy the string on a hit in the hash.
    7878    if (document().isHTMLDocument()) {
    79         if (!tagQName().hasPrefix())
     79        if (LIKELY(!tagQName().hasPrefix()))
    8080            return tagQName().localNameUpper();
    81         return Element::nodeName().upper();
     81        return Element::nodeName().convertToASCIIUppercase();
    8282    }
    8383    return Element::nodeName();
Note: See TracChangeset for help on using the changeset viewer.