From fcb9b5579a7c272cfcbb2d016a4e45d15e1cb28f Mon Sep 17 00:00:00 2001 From: Jeff Genovy <29107334+jefgen@users.noreply.github.com> Date: Wed, 11 Mar 2020 01:18:11 -0700 Subject: [PATCH] ICU-21013 Fix OOM not checked in vtzone.cpp Also change NULL to nullptr --- icu4c/source/i18n/vtzone.cpp | 284 +++++++++++++++++++++-------------- 1 file changed, 172 insertions(+), 112 deletions(-) diff --git a/icu4c/source/i18n/vtzone.cpp b/icu4c/source/i18n/vtzone.cpp index fa8c3390b81..81208ab96d7 100644 --- a/icu4c/source/i18n/vtzone.cpp +++ b/icu4c/source/i18n/vtzone.cpp @@ -526,15 +526,15 @@ rruleParseError: static TimeZoneRule* createRuleByRRULE(const UnicodeString& zonename, int rawOffset, int dstSavings, UDate start, UVector* dates, int fromOffset, UErrorCode& status) { if (U_FAILURE(status)) { - return NULL; + return nullptr; } - if (dates == NULL || dates->size() == 0) { + if (dates == nullptr || dates->size() == 0) { status = U_ILLEGAL_ARGUMENT_ERROR; - return NULL; + return nullptr; } int32_t i, j; - DateTimeRule *adtr = NULL; + DateTimeRule *adtr = nullptr; // Parse the first rule UnicodeString rrule = *((UnicodeString*)dates->elementAt(0)); @@ -545,7 +545,7 @@ static TimeZoneRule* createRuleByRRULE(const UnicodeString& zonename, int rawOff parseRRULE(rrule, month, dayOfWeek, nthDayOfWeek, days, daysCount, until, status); if (U_FAILURE(status)) { - return NULL; + return nullptr; } if (dates->size() == 1) { @@ -620,7 +620,7 @@ static TimeZoneRule* createRuleByRRULE(const UnicodeString& zonename, int rawOff int32_t tmp_daysCount = UPRV_LENGTHOF(tmp_days); parseRRULE(rrule, tmp_month, tmp_dayOfWeek, tmp_nthDayOfWeek, tmp_days, tmp_daysCount, tmp_until, status); if (U_FAILURE(status)) { - return NULL; + return nullptr; } // If UNTIL is newer than previous one, use the one if (tmp_until > until) { @@ -713,14 +713,14 @@ static TimeZoneRule* createRuleByRRULE(const UnicodeString& zonename, int rawOff // first Sunday after 15th day in the month adtr = new DateTimeRule(month, dayOfMonth, dayOfWeek, TRUE, startMID, DateTimeRule::WALL_TIME); } - if (adtr == NULL) { + if (adtr == nullptr) { goto unsupportedRRule; } return new AnnualTimeZoneRule(zonename, rawOffset, dstSavings, adtr, startYear, endYear); unsupportedRRule: status = U_INVALID_STATE_ERROR; - return NULL; + return nullptr; } /* @@ -729,34 +729,35 @@ unsupportedRRule: static TimeZoneRule* createRuleByRDATE(const UnicodeString& zonename, int32_t rawOffset, int32_t dstSavings, UDate start, UVector* dates, int32_t fromOffset, UErrorCode& status) { if (U_FAILURE(status)) { - return NULL; + return nullptr; } - TimeArrayTimeZoneRule *retVal = NULL; - if (dates == NULL || dates->size() == 0) { + TimeArrayTimeZoneRule *retVal = nullptr; + if (dates == nullptr || dates->size() == 0) { // When no RDATE line is provided, use start (DTSTART) // as the transition time - retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings, - &start, 1, DateTimeRule::UTC_TIME); + retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings, &start, 1, DateTimeRule::UTC_TIME); } else { // Create an array of transition times int32_t size = dates->size(); UDate* times = (UDate*)uprv_malloc(sizeof(UDate) * size); - if (times == NULL) { + if (times == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; - return NULL; + return nullptr; } for (int32_t i = 0; i < size; i++) { UnicodeString *datestr = (UnicodeString*)dates->elementAt(i); times[i] = parseDateTimeString(*datestr, fromOffset, status); if (U_FAILURE(status)) { uprv_free(times); - return NULL; + return nullptr; } } - retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings, - times, size, DateTimeRule::UTC_TIME); + retVal = new TimeArrayTimeZoneRule(zonename, rawOffset, dstSavings, times, size, DateTimeRule::UTC_TIME); uprv_free(times); } + if (retVal == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } return retVal; } @@ -800,12 +801,15 @@ static UBool isEquivalentDateRule(int32_t month, int32_t weekInMonth, int32_t da /* * Convert the rule to its equivalent rule using WALL_TIME mode. - * This function returns NULL when the specified DateTimeRule is already + * This function returns nullptr when the specified DateTimeRule is already * using WALL_TIME mode. */ -static DateTimeRule* toWallTimeRule(const DateTimeRule* rule, int32_t rawOffset, int32_t dstSavings) { +static DateTimeRule *toWallTimeRule(const DateTimeRule *rule, int32_t rawOffset, int32_t dstSavings, UErrorCode &status) { + if (U_FAILURE(status)) { + return nullptr; + } if (rule->getTimeRuleType() == DateTimeRule::WALL_TIME) { - return NULL; + return nullptr; } int32_t wallt = rule->getRuleMillisInDay(); if (rule->getTimeRuleType() == DateTimeRule::UTC_TIME) { @@ -864,12 +868,14 @@ static DateTimeRule* toWallTimeRule(const DateTimeRule* rule, int32_t rawOffset, } } // Create a new rule - DateTimeRule *modifiedRule; + DateTimeRule *modifiedRule = nullptr; if (dtype == DateTimeRule::DOM) { modifiedRule = new DateTimeRule(month, dom, wallt, DateTimeRule::WALL_TIME); } else { - modifiedRule = new DateTimeRule(month, dom, dow, - (dtype == DateTimeRule::DOW_GEQ_DOM), wallt, DateTimeRule::WALL_TIME); + modifiedRule = new DateTimeRule(month, dom, dow, (dtype == DateTimeRule::DOW_GEQ_DOM), wallt, DateTimeRule::WALL_TIME); + } + if (modifiedRule == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; } return modifiedRule; } @@ -956,21 +962,24 @@ VTZReader::read(void) { UOBJECT_DEFINE_RTTI_IMPLEMENTATION(VTimeZone) VTimeZone::VTimeZone() -: BasicTimeZone(), tz(NULL), vtzlines(NULL), +: BasicTimeZone(), tz(nullptr), vtzlines(nullptr), lastmod(MAX_MILLIS) { } VTimeZone::VTimeZone(const VTimeZone& source) -: BasicTimeZone(source), tz(NULL), vtzlines(NULL), +: BasicTimeZone(source), tz(nullptr), vtzlines(nullptr), tzurl(source.tzurl), lastmod(source.lastmod), olsonzid(source.olsonzid), icutzver(source.icutzver) { - if (source.tz != NULL) { + if (source.tz != nullptr) { tz = source.tz->clone(); } - if (source.vtzlines != NULL) { + if (source.vtzlines != nullptr) { UErrorCode status = U_ZERO_ERROR; int32_t size = source.vtzlines->size(); vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status); + if (vtzlines == nullptr) { + return; + } if (U_SUCCESS(status)) { for (int32_t i = 0; i < size; i++) { UnicodeString *line = (UnicodeString*)source.vtzlines->elementAt(i); @@ -980,17 +989,17 @@ VTimeZone::VTimeZone(const VTimeZone& source) } } } - if (U_FAILURE(status) && vtzlines != NULL) { + if (U_FAILURE(status) && vtzlines != nullptr) { delete vtzlines; } } } VTimeZone::~VTimeZone() { - if (tz != NULL) { + if (tz != nullptr) { delete tz; } - if (vtzlines != NULL) { + if (vtzlines != nullptr) { delete vtzlines; } } @@ -1002,21 +1011,21 @@ VTimeZone::operator=(const VTimeZone& right) { } if (*this != right) { BasicTimeZone::operator=(right); - if (tz != NULL) { + if (tz != nullptr) { delete tz; - tz = NULL; + tz = nullptr; } - if (right.tz != NULL) { + if (right.tz != nullptr) { tz = right.tz->clone(); } - if (vtzlines != NULL) { + if (vtzlines != nullptr) { delete vtzlines; } - if (right.vtzlines != NULL) { + if (right.vtzlines != nullptr) { UErrorCode status = U_ZERO_ERROR; int32_t size = right.vtzlines->size(); vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, size, status); - if (U_SUCCESS(status)) { + if (vtzlines != nullptr && U_SUCCESS(status)) { for (int32_t i = 0; i < size; i++) { UnicodeString *line = (UnicodeString*)right.vtzlines->elementAt(i); vtzlines->addElement(line->clone(), status); @@ -1025,9 +1034,9 @@ VTimeZone::operator=(const VTimeZone& right) { } } } - if (U_FAILURE(status) && vtzlines != NULL) { + if (U_FAILURE(status) && vtzlines != nullptr) { delete vtzlines; - vtzlines = NULL; + vtzlines = nullptr; } } tzurl = right.tzurl; @@ -1065,15 +1074,18 @@ VTimeZone::operator!=(const TimeZone& that) const { VTimeZone* VTimeZone::createVTimeZoneByID(const UnicodeString& ID) { VTimeZone *vtz = new VTimeZone(); + if (vtz == nullptr) { + return nullptr; + } vtz->tz = (BasicTimeZone*)TimeZone::createTimeZone(ID); vtz->tz->getID(vtz->olsonzid); // Set ICU tzdata version UErrorCode status = U_ZERO_ERROR; - UResourceBundle *bundle = NULL; - const UChar* versionStr = NULL; + UResourceBundle *bundle = nullptr; + const UChar* versionStr = nullptr; int32_t len = 0; - bundle = ures_openDirect(NULL, "zoneinfo64", &status); + bundle = ures_openDirect(nullptr, "zoneinfo64", &status); versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status); if (U_SUCCESS(status)) { vtz->icutzver.setTo(versionStr, len); @@ -1085,26 +1097,26 @@ VTimeZone::createVTimeZoneByID(const UnicodeString& ID) { VTimeZone* VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone, UErrorCode &status) { if (U_FAILURE(status)) { - return NULL; + return nullptr; } VTimeZone *vtz = new VTimeZone(); - if (vtz == NULL) { + if (vtz == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; - return NULL; + return nullptr; } vtz->tz = basic_time_zone.clone(); - if (vtz->tz == NULL) { + if (vtz->tz == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; delete vtz; - return NULL; + return nullptr; } vtz->tz->getID(vtz->olsonzid); // Set ICU tzdata version - UResourceBundle *bundle = NULL; - const UChar* versionStr = NULL; + UResourceBundle *bundle = nullptr; + const UChar* versionStr = nullptr; int32_t len = 0; - bundle = ures_openDirect(NULL, "zoneinfo64", &status); + bundle = ures_openDirect(nullptr, "zoneinfo64", &status); versionStr = ures_getStringByKey(bundle, "TZVersion", &len, &status); if (U_SUCCESS(status)) { vtz->icutzver.setTo(versionStr, len); @@ -1116,14 +1128,18 @@ VTimeZone::createVTimeZoneFromBasicTimeZone(const BasicTimeZone& basic_time_zone VTimeZone* VTimeZone::createVTimeZone(const UnicodeString& vtzdata, UErrorCode& status) { if (U_FAILURE(status)) { - return NULL; + return nullptr; } VTZReader reader(vtzdata); VTimeZone *vtz = new VTimeZone(); + if (vtz == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } vtz->load(reader, status); if (U_FAILURE(status)) { delete vtz; - return NULL; + return nullptr; } return vtz; } @@ -1251,6 +1267,9 @@ VTimeZone::getTimeZoneRules(const InitialTimeZoneRule*& initial, void VTimeZone::load(VTZReader& reader, UErrorCode& status) { vtzlines = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, DEFAULT_VTIMEZONE_LINES, status); + if (vtzlines == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } if (U_FAILURE(status)) { return; } @@ -1264,10 +1283,15 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) { if (ch == 0xFFFF) { // end of file if (start && line.startsWith(ICAL_END_VTIMEZONE, -1)) { - vtzlines->addElement(new UnicodeString(line), status); + LocalPointer element(new UnicodeString(line), status); if (U_FAILURE(status)) { goto cleanupVtzlines; } + vtzlines->addElement(element.getAlias(), status); + if (U_FAILURE(status)) { + goto cleanupVtzlines; + } + element.orphan(); // on success, vtzlines owns the object. success = TRUE; } break; @@ -1281,10 +1305,15 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) { // NOT followed by TAB/SP -> new line if (start) { if (line.length() > 0) { - vtzlines->addElement(new UnicodeString(line), status); + LocalPointer element(new UnicodeString(line), status); if (U_FAILURE(status)) { goto cleanupVtzlines; } + vtzlines->addElement(element.getAlias(), status); + if (U_FAILURE(status)) { + goto cleanupVtzlines; + } + element.orphan(); // on success, vtzlines owns the object. } } line.remove(); @@ -1299,19 +1328,29 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) { eol = TRUE; if (start) { if (line.startsWith(ICAL_END_VTIMEZONE, -1)) { - vtzlines->addElement(new UnicodeString(line), status); + LocalPointer element(new UnicodeString(line), status); if (U_FAILURE(status)) { goto cleanupVtzlines; } + vtzlines->addElement(element.getAlias(), status); + if (U_FAILURE(status)) { + goto cleanupVtzlines; + } + element.orphan(); // on success, vtzlines owns the object. success = TRUE; break; } } else { if (line.startsWith(ICAL_BEGIN_VTIMEZONE, -1)) { - vtzlines->addElement(new UnicodeString(line), status); + LocalPointer element(new UnicodeString(line), status); if (U_FAILURE(status)) { goto cleanupVtzlines; } + vtzlines->addElement(element.getAlias(), status); + if (U_FAILURE(status)) { + goto cleanupVtzlines; + } + element.orphan(); // on success, vtzlines owns the object. line.remove(); start = TRUE; eol = FALSE; @@ -1333,7 +1372,7 @@ VTimeZone::load(VTZReader& reader, UErrorCode& status) { cleanupVtzlines: delete vtzlines; - vtzlines = NULL; + vtzlines = nullptr; } // parser state @@ -1349,12 +1388,12 @@ VTimeZone::parse(UErrorCode& status) { if (U_FAILURE(status)) { return; } - if (vtzlines == NULL || vtzlines->size() == 0) { + if (vtzlines == nullptr || vtzlines->size() == 0) { status = U_INVALID_STATE_ERROR; return; } - InitialTimeZoneRule *initialRule = NULL; - RuleBasedTimeZone *rbtz = NULL; + InitialTimeZoneRule *initialRule = nullptr; + RuleBasedTimeZone *rbtz = nullptr; // timezone ID UnicodeString tzid; @@ -1373,13 +1412,16 @@ VTimeZone::parse(UErrorCode& status) { UnicodeString name; // RFC2445 prop name UnicodeString value; // RFC2445 prop value - UVector *dates = NULL; // list of RDATE or RRULE strings - UVector *rules = NULL; // list of TimeZoneRule instances + UVector *dates = nullptr; // list of RDATE or RRULE strings + UVector *rules = nullptr; // list of TimeZoneRule instances int32_t finalRuleIdx = -1; int32_t finalRuleCount = 0; rules = new UVector(status); + if (rules == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } if (U_FAILURE(status)) { goto cleanupParse; } @@ -1387,14 +1429,13 @@ VTimeZone::parse(UErrorCode& status) { rules->setDeleter(deleteTimeZoneRule); dates = new UVector(uprv_deleteUObject, uhash_compareUnicodeString, status); + if (dates == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } if (U_FAILURE(status)) { goto cleanupParse; } - if (rules == NULL || dates == NULL) { - status = U_MEMORY_ALLOCATION_ERROR; - goto cleanupParse; - } - + for (n = 0; n < vtzlines->size(); n++) { UnicodeString *line = (UnicodeString*)vtzlines->elementAt(n); int32_t valueSep = line->indexOf(COLON); @@ -1468,7 +1509,7 @@ VTimeZone::parse(UErrorCode& status) { // by comma UBool nextDate = TRUE; int32_t dstart = 0; - UnicodeString *dstr; + UnicodeString *dstr = nullptr; while (nextDate) { int32_t dend = value.indexOf(COMMA, dstart); if (dend == -1) { @@ -1477,7 +1518,11 @@ VTimeZone::parse(UErrorCode& status) { } else { dstr = new UnicodeString(value, dstart, dend - dstart); } - dates->addElement(dstr, status); + if (dstr == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } else { + dates->addElement(dstr, status); + } if (U_FAILURE(status)) { goto cleanupParse; } @@ -1489,10 +1534,15 @@ VTimeZone::parse(UErrorCode& status) { goto cleanupParse; } isRRULE = true; - dates->addElement(new UnicodeString(value), status); + LocalPointer element(new UnicodeString(value), status); if (U_FAILURE(status)) { goto cleanupParse; } + dates->addElement(element.getAlias(), status); + if (U_FAILURE(status)) { + goto cleanupParse; + } + element.orphan(); // on success, dates owns the object. } else if (name.compare(ICAL_END, -1) == 0) { // Mandatory properties if (dtstart.length() == 0 || from.length() == 0 || to.length() == 0) { @@ -1504,7 +1554,7 @@ VTimeZone::parse(UErrorCode& status) { } // create a time zone rule - TimeZoneRule *rule = NULL; + TimeZoneRule *rule = nullptr; int32_t fromOffset = 0; int32_t toOffset = 0; int32_t rawOffset = 0; @@ -1546,7 +1596,7 @@ VTimeZone::parse(UErrorCode& status) { } else { rule = createRuleByRDATE(zonename, rawOffset, dstSavings, start, dates, fromOffset, status); } - if (U_FAILURE(status) || rule == NULL) { + if (U_FAILURE(status) || rule == nullptr) { goto cleanupParse; } else { UBool startAvail = rule->getFirstStart(fromOffset, 0, actualStart); @@ -1586,25 +1636,24 @@ VTimeZone::parse(UErrorCode& status) { // Create a initial rule getDefaultTZName(tzid, FALSE, zonename); - initialRule = new InitialTimeZoneRule(zonename, - initialRawOffset, initialDSTSavings); - if (initialRule == NULL) { + initialRule = new InitialTimeZoneRule(zonename, initialRawOffset, initialDSTSavings); + if (initialRule == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; goto cleanupParse; } // Finally, create the RuleBasedTimeZone rbtz = new RuleBasedTimeZone(tzid, initialRule); - if (rbtz == NULL) { + if (rbtz == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; goto cleanupParse; } - initialRule = NULL; // already adopted by RBTZ, no need to delete + initialRule = nullptr; // already adopted by RBTZ, no need to delete for (n = 0; n < rules->size(); n++) { TimeZoneRule *r = (TimeZoneRule*)rules->elementAt(n); AnnualTimeZoneRule *atzrule = dynamic_cast(r); - if (atzrule != NULL) { + if (atzrule != nullptr) { if (atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) { finalRuleCount++; finalRuleIdx = n; @@ -1649,7 +1698,7 @@ VTimeZone::parse(UErrorCode& status) { } } - TimeZoneRule *newRule; + TimeZoneRule *newRule = nullptr; UnicodeString tznam; if (start == finalStart) { // Transform this into a single transition @@ -1672,7 +1721,7 @@ VTimeZone::parse(UErrorCode& status) { finalRule->getStartYear(), y); } - if (newRule == NULL) { + if (newRule == nullptr) { status = U_MEMORY_ALLOCATION_ERROR; goto cleanupParse; } @@ -1704,20 +1753,20 @@ VTimeZone::parse(UErrorCode& status) { return; cleanupParse: - if (rules != NULL) { + if (rules != nullptr) { while (!rules->isEmpty()) { TimeZoneRule *r = (TimeZoneRule*)rules->orphanElementAt(0); delete r; } delete rules; } - if (dates != NULL) { + if (dates != nullptr) { delete dates; } - if (initialRule != NULL) { + if (initialRule != nullptr) { delete initialRule; } - if (rbtz != NULL) { + if (rbtz != nullptr) { delete rbtz; } return; @@ -1725,7 +1774,7 @@ cleanupParse: void VTimeZone::write(VTZWriter& writer, UErrorCode& status) const { - if (vtzlines != NULL) { + if (vtzlines != nullptr) { for (int32_t i = 0; i < vtzlines->size(); i++) { UnicodeString *line = (UnicodeString*)vtzlines->elementAt(i); if (line->startsWith(ICAL_TZURL, -1) @@ -1765,8 +1814,8 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const { if (U_FAILURE(status)) { return; } - InitialTimeZoneRule *initial = NULL; - UVector *transitionRules = NULL; + InitialTimeZoneRule *initial = nullptr; + UVector *transitionRules = nullptr; UVector customProps(uprv_deleteUObject, uhash_compareUnicodeString, status); UnicodeString tzid; @@ -1779,7 +1828,7 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const { // Create a RuleBasedTimeZone with the subset rule getID(tzid); RuleBasedTimeZone rbtz(tzid, initial); - if (transitionRules != NULL) { + if (transitionRules != nullptr) { while (!transitionRules->isEmpty()) { TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0); rbtz.addTransitionRule(tr, status); @@ -1788,7 +1837,7 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const { } } delete transitionRules; - transitionRules = NULL; + transitionRules = nullptr; } rbtz.complete(status); if (U_FAILURE(status)) { @@ -1797,6 +1846,10 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const { if (olsonzid.length() > 0 && icutzver.length() > 0) { UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP); + if (icutzprop == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + goto cleanupWritePartial; + } icutzprop->append(olsonzid); icutzprop->append((UChar)0x005B/*'['*/); icutzprop->append(icutzver); @@ -1813,10 +1866,10 @@ VTimeZone::write(UDate start, VTZWriter& writer, UErrorCode& status) const { return; cleanupWritePartial: - if (initial != NULL) { + if (initial != nullptr) { delete initial; } - if (transitionRules != NULL) { + if (transitionRules != nullptr) { while (!transitionRules->isEmpty()) { TimeZoneRule *tr = (TimeZoneRule*)transitionRules->orphanElementAt(0); delete tr; @@ -1835,14 +1888,14 @@ VTimeZone::writeSimple(UDate time, VTZWriter& writer, UErrorCode& status) const UnicodeString tzid; // Extract simple rules - InitialTimeZoneRule *initial = NULL; - AnnualTimeZoneRule *std = NULL, *dst = NULL; + InitialTimeZoneRule *initial = nullptr; + AnnualTimeZoneRule *std = nullptr, *dst = nullptr; getSimpleRulesNear(time, initial, std, dst, status); if (U_SUCCESS(status)) { // Create a RuleBasedTimeZone with the subset rule getID(tzid); RuleBasedTimeZone rbtz(tzid, initial); - if (std != NULL && dst != NULL) { + if (std != nullptr && dst != nullptr) { rbtz.addTransitionRule(std, status); rbtz.addTransitionRule(dst, status); } @@ -1852,6 +1905,10 @@ VTimeZone::writeSimple(UDate time, VTZWriter& writer, UErrorCode& status) const if (olsonzid.length() > 0 && icutzver.length() > 0) { UnicodeString *icutzprop = new UnicodeString(ICU_TZINFO_PROP); + if (icutzprop == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + goto cleanupWriteSimple; + } icutzprop->append(olsonzid); icutzprop->append((UChar)0x005B/*'['*/); icutzprop->append(icutzver); @@ -1869,13 +1926,13 @@ VTimeZone::writeSimple(UDate time, VTZWriter& writer, UErrorCode& status) const return; cleanupWriteSimple: - if (initial != NULL) { + if (initial != nullptr) { delete initial; } - if (std != NULL) { + if (std != nullptr) { delete std; } - if (dst != NULL) { + if (dst != nullptr) { delete dst; } } @@ -1891,7 +1948,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, return; } - if (customProps != NULL) { + if (customProps != nullptr) { for (int32_t i = 0; i < customProps->size(); i++) { UnicodeString *custprop = (UnicodeString*)customProps->elementAt(i); w.write(*custprop); @@ -1912,7 +1969,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, UDate dstStartTime = 0.0; UDate dstUntilTime = 0.0; int32_t dstCount = 0; - AnnualTimeZoneRule *finalDstRule = NULL; + AnnualTimeZoneRule *finalDstRule = nullptr; UnicodeString stdName; int32_t stdFromOffset = 0; @@ -1926,7 +1983,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, UDate stdStartTime = 0.0; UDate stdUntilTime = 0.0; int32_t stdCount = 0; - AnnualTimeZoneRule *finalStdRule = NULL; + AnnualTimeZoneRule *finalStdRule = nullptr; int32_t year, month, dom, dow, doy, mid; UBool hasTransitions = FALSE; @@ -1953,8 +2010,8 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, UBool sameRule = FALSE; const AnnualTimeZoneRule *atzrule; if (isDst) { - if (finalDstRule == NULL - && (atzrule = dynamic_cast(tzt.getTo())) != NULL + if (finalDstRule == nullptr + && (atzrule = dynamic_cast(tzt.getTo())) != nullptr && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR ) { finalDstRule = atzrule->clone(); @@ -2000,12 +2057,12 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, dstStartTime = dstUntilTime = t; dstCount = 1; } - if (finalStdRule != NULL && finalDstRule != NULL) { + if (finalStdRule != nullptr && finalDstRule != nullptr) { break; } } else { - if (finalStdRule == NULL - && (atzrule = dynamic_cast(tzt.getTo())) != NULL + if (finalStdRule == nullptr + && (atzrule = dynamic_cast(tzt.getTo())) != nullptr && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR ) { finalStdRule = atzrule->clone(); @@ -2051,7 +2108,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, stdStartTime = stdUntilTime = t; stdCount = 1; } - if (finalStdRule != NULL && finalDstRule != NULL) { + if (finalStdRule != nullptr && finalDstRule != nullptr) { break; } } @@ -2075,7 +2132,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, } } else { if (dstCount > 0) { - if (finalDstRule == NULL) { + if (finalDstRule == nullptr) { if (dstCount == 1) { writeZonePropsByTime(w, TRUE, dstName, dstFromOffset, dstToOffset, dstStartTime, TRUE, status); @@ -2117,7 +2174,7 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, } } if (stdCount > 0) { - if (finalStdRule == NULL) { + if (finalStdRule == nullptr) { if (stdCount == 1) { writeZonePropsByTime(w, FALSE, stdName, stdFromOffset, stdToOffset, stdStartTime, TRUE, status); @@ -2163,10 +2220,10 @@ VTimeZone::writeZone(VTZWriter& w, BasicTimeZone& basictz, cleanupWriteZone: - if (finalStdRule != NULL) { + if (finalStdRule != nullptr) { delete finalStdRule; } - if (finalDstRule != NULL) { + if (finalDstRule != nullptr) { delete finalDstRule; } } @@ -2479,8 +2536,11 @@ VTimeZone::writeFinalRule(VTZWriter& writer, UBool isDst, const AnnualTimeZoneRu return; } UBool modifiedRule = TRUE; - const DateTimeRule *dtrule = toWallTimeRule(rule->getRule(), fromRawOffset, fromDSTSavings); - if (dtrule == NULL) { + const DateTimeRule *dtrule = toWallTimeRule(rule->getRule(), fromRawOffset, fromDSTSavings, status); + if (U_FAILURE(status)) { + return; + } + if (dtrule == nullptr) { modifiedRule = FALSE; dtrule = rule->getRule(); }