]> granicus.if.org Git - icu/commitdiff
ICU-21919 Fix buffer overflow bug in Dutch accented IJ titlecase
authorElango Cheran <elango@unicode.org>
Tue, 22 Feb 2022 18:28:12 +0000 (18:28 +0000)
committerElango <elango@unicode.org>
Wed, 23 Feb 2022 20:00:36 +0000 (12:00 -0800)
See #1990

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

index b6e7f2b744d57cb97811305274001548250ac8ec..f727560b57167f071a2c38ab44516f2942a1f39a 100644 (file)
@@ -437,6 +437,7 @@ constexpr uint8_t ACUTE_BYTE1 = u8"\u0301"[1];
  */
 int32_t maybeTitleDutchIJ(const uint8_t *src, UChar32 c, int32_t start, int32_t segmentLimit,
                           ByteSink &sink, uint32_t options, icu::Edits *edits, UErrorCode &errorCode) {
+    U_ASSERT(start < segmentLimit);
 
     int32_t index = start;
     bool withAcute = false;
@@ -594,7 +595,7 @@ ucasemap_internalUTF8ToTitle(
                 }
 
                 /* Special case Dutch IJ titlecasing */
-                if (titleStart+1 < index &&
+                if (titleLimit < index &&
                     caseLocale == UCASE_LOC_DUTCH) {
                     if (c < 0) {
                         c = ~c;
index acd37a598ab12c4929b2dd096060417fd3336f93..43910ea520984ecf317c4e22919e1725502cd449 100644 (file)
@@ -416,6 +416,7 @@ namespace {
 int32_t maybeTitleDutchIJ(const UChar *src, UChar32 c, int32_t start, int32_t segmentLimit,
                           UChar *dest, int32_t &destIndex, int32_t destCapacity, uint32_t options,
                           icu::Edits *edits) {
+    U_ASSERT(start < segmentLimit);
 
     int32_t index = start;
     bool withAcute = false;
index 14df2a36bdb4f626204e9f70de06f72641199e5a..b5eff9f0af800b73f8b7daa25743ae24478820f4 100644 (file)
@@ -741,6 +741,9 @@ void StringCaseTest::TestDutchTitle() {
         {u"íjabc\u0308",        u"Íjabc\u0308",       u"Í"},
         {u"íj́abc\U0001D16E",    u"ÍJ́abc\U0001D16E",   u"ÍJ"},
         {u"íjabc\u1ABE",        u"Íjabc\u1ABE",       u"Í"},
+
+        // Bug ICU-21919
+        {u"Í",                  u"Í",                 u""},
     };
 
     for (const auto& cas : dutchTitleTestCases) {
@@ -763,7 +766,6 @@ void StringCaseTest::TestDutchTitle() {
                 testOptions
             );
         }
-        
     }
 }
 #endif
index 052e52c592f4806ef9eec09d9bc02d0d5f95dabf..c6521a580227839e424883afe31d485b59e7b459 100644 (file)
@@ -794,6 +794,8 @@ public final class CaseMapImpl {
     private static <A extends Appendable> int maybeTitleDutchIJ(
             CharSequence src, int c, int start, int segmentLimit,
             A dest, int options, Edits edits) throws IOException {
+        assert start < segmentLimit;
+
         int index = start;
         boolean withAcute = false;
 
index f56f2950e31d3fa39a04214483f50bb2926be199..b929dfa9ee5ae77f1cc0c7e10d6de13ca01c5034 100644 (file)
@@ -497,6 +497,9 @@ public final class UCharacterCaseTest extends TestFmwk
                 {"íjabc\u0308",        "Íjabc\u0308",       "Í"},
                 {"íj́abc\uD834\uDD6E",  "ÍJ́abc\uD834\uDD6E", "ÍJ"},
                 {"íjabc\u1ABE",        "Íjabc\u1ABE",       "Í"},
+
+                // Bug ICU-21919
+                {"Í",                  "Í",                 ""},
         };
 
         for (String[] caseDatum : dutchIJCasesData) {