]> granicus.if.org Git - icu/commitdiff
ICU-13851 case mapping data: when fetching delta make sure to read from start of...
authorMarkus Scherer <markus.icu@gmail.com>
Sun, 24 Jun 2018 21:12:22 +0000 (21:12 +0000)
committerJeff Genovy <29107334+jefgen@users.noreply.github.com>
Wed, 15 Aug 2018 18:36:47 +0000 (11:36 -0700)
X-SVN-Rev: 41550

icu4c/source/common/ucase.cpp
icu4c/source/test/intltest/strcase.cpp
icu4j/main/classes/core/src/com/ibm/icu/impl/UCaseProps.java
icu4j/main/tests/core/src/com/ibm/icu/dev/test/lang/UCharacterCaseTest.java

index cbd5a6efb56cc8f1bd74bf02646dd780c30b38cd..8414c527d49c9f1cb8995c7a80c2afbebb2a1ad0 100644 (file)
@@ -270,6 +270,7 @@ ucase_addCaseClosure(UChar32 c, const USetAdder *sa) {
             }
         }
         if(HAS_SLOT(excWord, UCASE_EXC_DELTA)) {
+            pe=pe0;
             int32_t delta;
             GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
             sa->add(sa->set, (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta);
@@ -1167,7 +1168,7 @@ ucase_toFullLower(UChar32 c,
 
         if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
             int32_t delta;
-            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
             return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
         }
         if(HAS_SLOT(excWord, UCASE_EXC_LOWER)) {
@@ -1261,7 +1262,7 @@ toUpperOrTitle(UChar32 c,
 
         if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_GET_TYPE(props)==UCASE_LOWER) {
             int32_t delta;
-            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
             return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
         }
         if(!upperNotTitle && HAS_SLOT(excWord, UCASE_EXC_TITLE)) {
@@ -1469,7 +1470,7 @@ ucase_toFullFolding(UChar32 c,
         }
         if(HAS_SLOT(excWord, UCASE_EXC_DELTA) && UCASE_IS_UPPER_OR_TITLE(props)) {
             int32_t delta;
-            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe, delta);
+            GET_SLOT_VALUE(excWord, UCASE_EXC_DELTA, pe2, delta);
             return (excWord&UCASE_EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
         }
         if(HAS_SLOT(excWord, UCASE_EXC_FOLD)) {
index fe983da181cf312ef5626ff3ca891b9145d220be..3fb0584992522d06805b91dbd999137a0d0bd299 100644 (file)
@@ -68,6 +68,7 @@ public:
     void TestBug13127();
     void TestInPlaceTitle();
     void TestCaseMapEditsIteratorDocs();
+    void TestCaseMapGreekExtended();
 
 private:
     void assertGreekUpper(const char16_t *s, const char16_t *expected);
@@ -113,6 +114,7 @@ StringCaseTest::runIndexedTest(int32_t index, UBool exec, const char *&name, cha
     TESTCASE_AUTO(TestInPlaceTitle);
 #endif
     TESTCASE_AUTO(TestCaseMapEditsIteratorDocs);
+    TESTCASE_AUTO(TestCaseMapGreekExtended);
     TESTCASE_AUTO_END;
 }
 
@@ -1685,4 +1687,17 @@ void StringCaseTest::TestCaseMapEditsIteratorDocs() {
     }
 }
 
+void StringCaseTest::TestCaseMapGreekExtended() {
+    // Ticket 13851
+    UnicodeString s(u"\u1F80\u1F88\u1FFC");
+    UnicodeString result(s);
+    result.toLower(Locale::getRoot());
+    assertEquals(u"lower", u"\u1F80\u1F80\u1FF3", result);
+#if !UCONFIG_NO_BREAK_ITERATION
+    result = s;
+    result.toTitle(nullptr, Locale::getRoot());
+    assertEquals(u"title", u"\u1F88\u1F80\u1FF3", result);
+#endif
+}
+
 //#endif
index ae267bbbe7997b268f7a87b58b32a4385ef41bbf..a925507eed6568c519083c949999f540dc35f0a6 100644 (file)
@@ -318,6 +318,7 @@ public final class UCaseProps {
                 }
             }
             if(hasSlot(excWord, EXC_DELTA)) {
+                excOffset=excOffset0;
                 int delta=getSlotValue(excWord, EXC_DELTA, excOffset);
                 set.add((excWord&EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta);
             }
@@ -1131,7 +1132,7 @@ public final class UCaseProps {
             }
 
             if(hasSlot(excWord, EXC_DELTA) && isUpperOrTitleFromProps(props)) {
-                int delta=getSlotValue(excWord, EXC_DELTA, excOffset);
+                int delta=getSlotValue(excWord, EXC_DELTA, excOffset2);
                 return (excWord&EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
             }
             if(hasSlot(excWord, EXC_LOWER)) {
@@ -1227,7 +1228,7 @@ public final class UCaseProps {
             }
 
             if(hasSlot(excWord, EXC_DELTA) && getTypeFromProps(props)==LOWER) {
-                int delta=getSlotValue(excWord, EXC_DELTA, excOffset);
+                int delta=getSlotValue(excWord, EXC_DELTA, excOffset2);
                 return (excWord&EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
             }
             if(!upperNotTitle && hasSlot(excWord, EXC_TITLE)) {
@@ -1448,7 +1449,7 @@ public final class UCaseProps {
                 return ~c;
             }
             if(hasSlot(excWord, EXC_DELTA) && isUpperOrTitleFromProps(props)) {
-                int delta=getSlotValue(excWord, EXC_DELTA, excOffset);
+                int delta=getSlotValue(excWord, EXC_DELTA, excOffset2);
                 return (excWord&EXC_DELTA_IS_NEGATIVE)==0 ? c+delta : c-delta;
             }
             if(hasSlot(excWord, EXC_FOLD)) {
index 7ee1f55c5a4c499feb3a42ac4beca23d5609a43b..1649a718d708be75dd8c11d749446e27bbf60287 100644 (file)
@@ -1493,6 +1493,16 @@ public final class UCharacterCaseTest extends TestFmwk
         }
     }
 
+    @Test
+    public void TestCaseMapGreekExtended() {
+        // Ticket 13851
+        String s = "\u1F80\u1F88\u1FFC";
+        String result = CaseMap.toLower().apply(Locale.ROOT,  s);
+        assertEquals("lower", "\u1F80\u1F80\u1FF3", result);
+        result = CaseMap.toTitle().apply(Locale.ROOT, null, s);
+        assertEquals("title", "\u1F88\u1F80\u1FF3", result);
+    }
+
     // private data members - test data --------------------------------------
 
     private static final Locale TURKISH_LOCALE_ = new Locale("tr", "TR");