diff --git a/icu4c/source/i18n/tznames_impl.cpp b/icu4c/source/i18n/tznames_impl.cpp index ec0ef8ec40f..c315d2b5d5b 100644 --- a/icu4c/source/i18n/tznames_impl.cpp +++ b/icu4c/source/i18n/tznames_impl.cpp @@ -34,6 +34,7 @@ #include "ureslocs.h" #include "zonemeta.h" #include "ucln_in.h" +#include "uinvchar.h" #include "uvector.h" #include "olsontz.h" @@ -2280,6 +2281,10 @@ TZDBTimeZoneNames::getMetaZoneNames(const UnicodeString& mzID, UErrorCode& statu return nullptr; } mzIDKey[mzID.length()] = 0; + if (!uprv_isInvariantUString(mzIDKey, mzID.length())) { + status = U_ILLEGAL_ARGUMENT_ERROR; + return nullptr; + } static UMutex gTZDBNamesMapLock; umtx_lock(&gTZDBNamesMapLock); diff --git a/icu4c/source/test/intltest/tzfmttst.cpp b/icu4c/source/test/intltest/tzfmttst.cpp index ddb49946234..247939a8d28 100644 --- a/icu4c/source/test/intltest/tzfmttst.cpp +++ b/icu4c/source/test/intltest/tzfmttst.cpp @@ -89,6 +89,7 @@ TimeZoneFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name TESTCASE(9, TestCentralTime); TESTCASE(10, TestBogusLocale); TESTCASE(11, Test22614GetMetaZoneNamesNotCrash); + TESTCASE(12, Test22615NonASCIIID); default: name = ""; break; } } @@ -1316,6 +1317,52 @@ TimeZoneFormatTest::TestFormatCustomZone() { } } +void +TimeZoneFormatTest::Test22615NonASCIIID() { + UErrorCode status = U_ZERO_ERROR; + LocalPointer tzdb(TimeZoneNames::createTZDBInstance(Locale("en"), status)); + // A test to ensure under the debugging build non ASCII id will not cause + // internal assertion error. + UnicodeString id(9, u'\u00C0', 8); + UnicodeString output; + tzdb->getMetaZoneDisplayName(id, UTZNM_SHORT_STANDARD, output); + assertTrue("getMetaZoneID of non ASCII id should return bogus string", + output.isBogus()); + + status = U_ZERO_ERROR; + std::unique_ptr enumeration( + tzdb->getAvailableMetaZoneIDs(id, status)); + assertSuccess("getAvailableMetaZoneIDs should success", status); + assertEquals("getAvailableMetaZoneIDs with non ASCII id return 0 ids", + 0, enumeration->count(status)); + assertSuccess("count should success", status); + + output.remove(); + tzdb->getMetaZoneID(id, 0, output); + assertTrue("getMetaZoneID of non ASCII id should return bogus string", + output.isBogus()); + + output.remove(); + tzdb->getMetaZoneDisplayName(id, UTZNM_EXEMPLAR_LOCATION, output); + assertTrue("getMetaZoneDisplayName of non ASCII id should return bogus string", + output.isBogus()); + + output.remove(); + tzdb->getTimeZoneDisplayName(id, UTZNM_SHORT_DAYLIGHT, output); + assertTrue("getTimeZoneDisplayName of non ASCII id should return bogus string", + output.isBogus()); + + output.remove(); + tzdb->getExemplarLocationName(id, output); + assertTrue("getExemplarLocationName of non ASCII id should return bogus string", + output.isBogus()); + + output.remove(); + tzdb->getDisplayName(id, UTZNM_LONG_GENERIC, 0, output); + assertTrue("getDisplayName of non ASCII id should return bogus string", + output.isBogus()); +} + void TimeZoneFormatTest::Test22614GetMetaZoneNamesNotCrash() { UErrorCode status = U_ZERO_ERROR; diff --git a/icu4c/source/test/intltest/tzfmttst.h b/icu4c/source/test/intltest/tzfmttst.h index 1bcae2955bc..88258cf9b2b 100644 --- a/icu4c/source/test/intltest/tzfmttst.h +++ b/icu4c/source/test/intltest/tzfmttst.h @@ -33,6 +33,7 @@ class TimeZoneFormatTest : public IntlTest { void TestCentralTime(); void TestBogusLocale(); void Test22614GetMetaZoneNamesNotCrash(); + void Test22615NonASCIIID(); void RunTimeRoundTripTests(int32_t threadNumber); void RunAdoptDefaultThreadSafeTests(int32_t threadNumber);