From: Yoshito Umaoka Date: Thu, 14 Sep 2017 02:37:44 +0000 (+0000) Subject: ICU-13312 Fixed getDisplayName crash issue caused by TZDBTimeZoneNames, added a test... X-Git-Tag: release-60-rc~144 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ed012e1bfba52180470dd406721e5b81f8b7d37b;p=icu ICU-13312 Fixed getDisplayName crash issue caused by TZDBTimeZoneNames, added a test case for the fix that interate through all time zones. X-SVN-Rev: 40412 --- diff --git a/icu4c/source/i18n/tznames_impl.cpp b/icu4c/source/i18n/tznames_impl.cpp index 8accb84d2d5..7127b176751 100644 --- a/icu4c/source/i18n/tznames_impl.cpp +++ b/icu4c/source/i18n/tznames_impl.cpp @@ -2056,6 +2056,9 @@ static void U_CALLCONV prepareFind(UErrorCode &status) { if (U_SUCCESS(status)) { while ((mzID = mzIDs->snext(status)) && U_SUCCESS(status)) { const TZDBNames *names = TZDBTimeZoneNames::getMetaZoneNames(*mzID, status); + if (U_FAILURE(status)) { + break; + } if (names == NULL) { continue; } @@ -2187,9 +2190,11 @@ TZDBTimeZoneNames::getMetaZoneDisplayName(const UnicodeString& mzID, UErrorCode status = U_ZERO_ERROR; const TZDBNames *tzdbNames = TZDBTimeZoneNames::getMetaZoneNames(mzID, status); if (U_SUCCESS(status)) { - const UChar *s = tzdbNames->getName(type); - if (s != NULL) { - name.setTo(TRUE, s, -1); + if (tzdbNames != NULL) { + const UChar *s = tzdbNames->getName(type); + if (s != NULL) { + name.setTo(TRUE, s, -1); + } } } diff --git a/icu4c/source/i18n/tznames_impl.h b/icu4c/source/i18n/tznames_impl.h index 9251f9ef470..0aac1de5545 100644 --- a/icu4c/source/i18n/tznames_impl.h +++ b/icu4c/source/i18n/tznames_impl.h @@ -246,6 +246,8 @@ public: TimeZoneNames::MatchInfoCollection* find(const UnicodeString& text, int32_t start, uint32_t types, UErrorCode& status) const; + // When TZDBNames for the metazone is not available, this method returns NULL, + // but does NOT set U_MISSING_RESOURCE_ERROR to status. static const TZDBNames* getMetaZoneNames(const UnicodeString& mzId, UErrorCode& status); private: diff --git a/icu4c/source/test/intltest/tzfmttst.cpp b/icu4c/source/test/intltest/tzfmttst.cpp index 9557b144921..b74ee5ffc71 100644 --- a/icu4c/source/test/intltest/tzfmttst.cpp +++ b/icu4c/source/test/intltest/tzfmttst.cpp @@ -83,7 +83,8 @@ TimeZoneFormatTest::runIndexedTest( int32_t index, UBool exec, const char* &name TESTCASE(4, TestFormat); TESTCASE(5, TestFormatTZDBNames); TESTCASE(6, TestFormatCustomZone); - default: name = ""; break; + TESTCASE(7, TestFormatTZDBNamesAllZoneCoverage); + default: name = ""; break; } } @@ -1251,5 +1252,44 @@ TimeZoneFormatTest::TestFormatCustomZone(void) { } } +void +TimeZoneFormatTest::TestFormatTZDBNamesAllZoneCoverage(void) { + UErrorCode status = U_ZERO_ERROR; + LocalPointer tzids(TimeZone::createEnumeration()); + const UnicodeString *tzid; + LocalPointer tzdbNames(TimeZoneNames::createTZDBInstance(Locale("en"), status)); + UDate now = Calendar::getNow(); + UnicodeString mzId; + UnicodeString name; + while ((tzid = tzids->snext(status))) { + logln("Zone: " + *tzid); + LocalPointer tz(TimeZone::createTimeZone(*tzid)); + tzdbNames->getMetaZoneID(*tzid, now, mzId); + if (mzId.isBogus()) { + logln((UnicodeString)"Meta zone: "); + } else { + logln((UnicodeString)"Meta zone: " + mzId); + } + + // mzID could be bogus here + tzdbNames->getMetaZoneDisplayName(mzId, UTZNM_SHORT_STANDARD, name); + // name could be bogus here + if (name.isBogus()) { + logln((UnicodeString)"Meta zone short standard name: "); + } + else { + logln((UnicodeString)"Meta zone short standard name: " + name); + } + + tzdbNames->getMetaZoneDisplayName(mzId, UTZNM_SHORT_DAYLIGHT, name); + // name could be bogus here + if (name.isBogus()) { + logln((UnicodeString)"Meta zone short daylight name: "); + } + else { + logln((UnicodeString)"Meta zone short daylight name: " + name); + } + } +} #endif /* #if !UCONFIG_NO_FORMATTING */ diff --git a/icu4c/source/test/intltest/tzfmttst.h b/icu4c/source/test/intltest/tzfmttst.h index 0bf91ae0e8e..89ece5e2e06 100644 --- a/icu4c/source/test/intltest/tzfmttst.h +++ b/icu4c/source/test/intltest/tzfmttst.h @@ -28,6 +28,7 @@ class TimeZoneFormatTest : public IntlTest { void TestFormat(void); void TestFormatTZDBNames(void); void TestFormatCustomZone(void); + void TestFormatTZDBNamesAllZoneCoverage(void); void RunTimeRoundTripTests(int32_t threadNumber); };