Skip to content

Commit

Permalink
Greek uppercase transforms fail for some characters
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=237953
rdar://problem/90364897

Reviewed by Chris Dumez.

Skip the fast path when uppercasing in the "el" locale.

* LayoutTests/TestExpectations: Expect more tests to pass.

* Source/WTF/wtf/text/StringImpl.cpp:
(WTF::needsTurkishCasingRules): Tweaked comment.
(WTF::needsGreekUppercasingRules): Added.
(WTF::StringImpl::convertToUppercaseWithLocale): Don't use fast path when
needsGreekUppercasingRules returns true.

Canonical link: https://commits.webkit.org/274036@main
  • Loading branch information
darinadler committed Feb 3, 2024
1 parent 674f7d1 commit de609ec
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 21 deletions.
16 changes: 2 additions & 14 deletions LayoutTests/TestExpectations
Original file line number Diff line number Diff line change
Expand Up @@ -2999,23 +2999,11 @@ webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/text-encoding/s
webkit.org/b/214290 imported/w3c/web-platform-tests/css/css-text/text-indent/text-indent-tab-positions-001.html [ ImageOnlyFailure ]
webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-flex-item-001.html [ ImageOnlyFailure ]
webkit.org/b/240837 imported/w3c/web-platform-tests/css/css-text/text-indent/anonymous-grid-item-001.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-018.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-020.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-026.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-028.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-026.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-028.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-tailoring-001.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-tailoring-002.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-tailoring-002a.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-tailoring-003.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-tailoring-005.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-006.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-018.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-019.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-020.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-021.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-039.html [ ImageOnlyFailure ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-103.html [ ImageOnlyFailure Pass ]
webkit.org/b/183258 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-upperlower-104.html [ ImageOnlyFailure Pass ]
webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-capitalize-033.html [ ImageOnlyFailure ]
webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-shaping-003.html [ ImageOnlyFailure ]
webkit.org/b/195275 imported/w3c/web-platform-tests/css/css-text/text-transform/text-transform-shaping-002.html [ ImageOnlyFailure ]
Expand Down
28 changes: 21 additions & 7 deletions Source/WTF/wtf/text/StringImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -519,14 +519,23 @@ Ref<StringImpl> StringImpl::convertToUppercaseWithoutLocale()

static inline bool needsTurkishCasingRules(const AtomString& localeIdentifier)
{
// Either "tr" or "az" locale, with case sensitive comparison and allowing for an ignored subtag.
// Either "tr" or "az" locale, with ASCII case insensitive comparison and allowing for an ignored subtag.
UChar first = localeIdentifier[0];
UChar second = localeIdentifier[1];
return ((isASCIIAlphaCaselessEqual(first, 't') && isASCIIAlphaCaselessEqual(second, 'r'))
|| (isASCIIAlphaCaselessEqual(first, 'a') && isASCIIAlphaCaselessEqual(second, 'z')))
&& (localeIdentifier.length() == 2 || localeIdentifier[2] == '-');
}

static inline bool needsGreekUppercasingRules(const AtomString& localeIdentifier)
{
// The "el" locale, with ASCII case insensitive comparison and allowing for an ignored subtag.
UChar first = localeIdentifier[0];
UChar second = localeIdentifier[1];
return (isASCIIAlphaCaselessEqual(first, 'e') && isASCIIAlphaCaselessEqual(second, 'l'))
&& (localeIdentifier.length() == 2 || localeIdentifier[2] == '-');
}

Ref<StringImpl> StringImpl::convertToLowercaseWithLocale(const AtomString& localeIdentifier)
{
// Use the more-optimized code path most of the time.
Expand Down Expand Up @@ -568,27 +577,32 @@ Ref<StringImpl> StringImpl::convertToUppercaseWithLocale(const AtomString& local
// Use the more-optimized code path most of the time.
// Assuming here that the only locale-specific lowercasing is the Turkish casing rules,
// and that the only affected character is lowercase "i".
if (!needsTurkishCasingRules(localeIdentifier) || find('i') == notFound)
const char* locale;
if (needsTurkishCasingRules(localeIdentifier) && find('i') != notFound) {
// Passing in the hardcoded locale "tr" is more efficient than
// allocating memory just to turn localeIdentifier into a C string, and we assume
// there is no difference between the uppercasing for "tr" and "az" locales.
locale = "tr";
} else if (needsGreekUppercasingRules(localeIdentifier))
locale = "el";
else
return convertToUppercaseWithoutLocale();

if (m_length > MaxLength)
CRASH();
int length = m_length;

// Below, we pass in the hardcoded locale "tr". Passing that is more efficient than
// allocating memory just to turn localeIdentifier into a C string, and we assume
// there is no difference between the uppercasing for "tr" and "az" locales.
auto upconvertedCharacters = StringView(*this).upconvertedCharacters();
const UChar* source16 = upconvertedCharacters;
UChar* data16;
auto newString = createUninitialized(length, data16);
UErrorCode status = U_ZERO_ERROR;
int realLength = u_strToUpper(data16, length, source16, length, "tr", &status);
int realLength = u_strToUpper(data16, length, source16, length, locale, &status);
if (U_SUCCESS(status) && realLength == length)
return newString;
newString = createUninitialized(realLength, data16);
status = U_ZERO_ERROR;
u_strToUpper(data16, realLength, source16, length, "tr", &status);
u_strToUpper(data16, realLength, source16, length, locale, &status);
if (U_FAILURE(status))
return *this;
return newString;
Expand Down

0 comments on commit de609ec

Please sign in to comment.