]> granicus.if.org Git - icu/commitdiff
ICU-21597 Fix Null-deref W in canonicalizeLocale
authorFrank Tang <ftang@chromium.org>
Wed, 28 Apr 2021 19:39:57 +0000 (12:39 -0700)
committerNorbert Runge <41129501+gnrunge@users.noreply.github.com>
Wed, 28 Apr 2021 22:37:08 +0000 (15:37 -0700)
icu4c/source/common/locid.cpp
icu4c/source/test/intltest/loctest.cpp
icu4c/source/test/intltest/loctest.h

index 3c6e5b0669080acce7116f47df597b01ef9f265b..4b7d21ee13dc94343b9120d8fc36f36fe5331e2e 100644 (file)
@@ -1571,6 +1571,7 @@ AliasReplacer::replaceTransformedExtensions(
             const char* tvalue = uprv_strchr(tkey, '-');
             if (tvalue == nullptr) {
                 status = U_ILLEGAL_ARGUMENT_ERROR;
+                return false;
             }
             const char* nextTKey = ultag_getTKeyStart(tvalue);
             if (nextTKey != nullptr) {
@@ -1591,8 +1592,11 @@ AliasReplacer::replaceTransformedExtensions(
              }
              const char* tfield = (const char*) tfields.elementAt(i);
              const char* tvalue = uprv_strchr(tfield, '-');
+             if (tvalue == nullptr) {
+                 status = U_ILLEGAL_ARGUMENT_ERROR;
+                 return false;
+             }
              // Split the "tkey-tvalue" pair string so that we can canonicalize the tvalue.
-             U_ASSERT(tvalue != nullptr);
              *((char*)tvalue++) = '\0'; // NULL terminate tkey
              output.append(tfield, status).append('-', status);
              const char* bcpTValue = ulocimp_toBcpType(tfield, tvalue, nullptr, nullptr);
index 5503b008b0c271b1a9d11643c44c14ef36c6af8f..fc156f3ca3a0437e38734d292dc6cca9fcfa7064 100644 (file)
@@ -284,6 +284,7 @@ void LocaleTest::runIndexedTest( int32_t index, UBool exec, const char* &name, c
     TESTCASE_AUTO(TestSetUnicodeKeywordValueNullInLongLocale);
     TESTCASE_AUTO(TestCanonicalize);
     TESTCASE_AUTO(TestLeak21419);
+    TESTCASE_AUTO(TestNullDereferenceWrite21597);
     TESTCASE_AUTO(TestLongLocaleSetKeywordAssign);
     TESTCASE_AUTO(TestLongLocaleSetKeywordMoveAssign);
     TESTCASE_AUTO_END;
@@ -5030,7 +5031,6 @@ void LocaleTest::TestCanonicalize(void)
         // alias of tvalue should be replaced
         { "en-t-m0-NaMeS", "en-t-m0-prprname" },
         { "en-t-s0-ascii-d0-NaMe", "en-t-d0-charname-s0-ascii" },
-
     };
     int32_t i;
     for (i=0; i < UPRV_LENGTHOF(testCases); i++) {
@@ -6586,3 +6586,10 @@ void LocaleTest::TestLeak21419() {
     l.canonicalize(status);
     status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
 }
+
+void LocaleTest::TestNullDereferenceWrite21597() {
+    IcuTestErrorCode status(*this, "TestNullDereferenceWrite21597");
+    Locale l = Locale("zu-t-q5-X1-vKf-KK-Ks-cO--Kc");
+    l.canonicalize(status);
+    status.expectErrorAndReset(U_ILLEGAL_ARGUMENT_ERROR);
+}
index 12a93bde53d92bc22834b79ba744b5f9ab5d6442..4a856c62239848e28ab9df575649b8262f032247 100644 (file)
@@ -156,6 +156,7 @@ public:
     void TestSetUnicodeKeywordValueInLongLocale();
     void TestSetUnicodeKeywordValueNullInLongLocale();
     void TestLeak21419();
+    void TestNullDereferenceWrite21597();
     void TestLongLocaleSetKeywordAssign();
     void TestLongLocaleSetKeywordMoveAssign();