ICU-21013 Fix OOM not checked in vtzone.cpp

Also change NULL to nullptr
diff --git a/icu4c/source/i18n/vtzone.cpp b/icu4c/source/i18n/vtzone.cpp
index fa8c339..81208ab 100644
--- a/icu4c/source/i18n/vtzone.cpp
+++ b/icu4c/source/i18n/vtzone.cpp
@@ -526,15 +526,15 @@
 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 @@
 
     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 @@
             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 @@
         // 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 @@
 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 @@
 
 /*
  * 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 @@
         }
     }
     // 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 @@
 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 @@
                 }
             }
         }
-        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 @@
     }
     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 @@
                     }
                 }
             }
-            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*
 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*
 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*
 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 @@
 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 @@
         if (ch == 0xFFFF) {
             // end of file
             if (start && line.startsWith(ICAL_END_VTIMEZONE, -1)) {
-                vtzlines->addElement(new UnicodeString(line), status);
+                LocalPointer<UnicodeString> 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 @@
                 // NOT followed by TAB/SP -> new line
                 if (start) {
                     if (line.length() > 0) {
-                        vtzlines->addElement(new UnicodeString(line), status);
+                        LocalPointer<UnicodeString> 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 @@
                 eol = TRUE;
                 if (start) {
                     if (line.startsWith(ICAL_END_VTIMEZONE, -1)) {
-                        vtzlines->addElement(new UnicodeString(line), status);
+                        LocalPointer<UnicodeString> 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<UnicodeString> 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 @@
 
 cleanupVtzlines:
     delete vtzlines;
-    vtzlines = NULL;
+    vtzlines = nullptr;
 }
 
 // parser state
@@ -1349,12 +1388,12 @@
     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 @@
     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 @@
     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 @@
                 // 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 @@
                     } 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 @@
                     goto cleanupParse;
                 }
                 isRRULE = true;
-                dates->addElement(new UnicodeString(value), status);
+                LocalPointer<UnicodeString> 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 @@
                 }
 
                 // 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 @@
                 } 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 @@
 
     // 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<AnnualTimeZoneRule *>(r);
-        if (atzrule != NULL) {
+        if (atzrule != nullptr) {
             if (atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR) {
                 finalRuleCount++;
                 finalRuleIdx = n;
@@ -1649,7 +1698,7 @@
                 }
             }
 
-            TimeZoneRule *newRule;
+            TimeZoneRule *newRule = nullptr;
             UnicodeString tznam;
             if (start == finalStart) {
                 // Transform this into a single transition
@@ -1672,7 +1721,7 @@
                         finalRule->getStartYear(),
                         y);
             }
-            if (newRule == NULL) {
+            if (newRule == nullptr) {
                 status = U_MEMORY_ALLOCATION_ERROR;
                 goto cleanupParse;
             }
@@ -1704,20 +1753,20 @@
     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 @@
 
 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 @@
     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 @@
     // 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 @@
             }
         }
         delete transitionRules;
-        transitionRules = NULL;
+        transitionRules = nullptr;
     }
     rbtz.complete(status);
     if (U_FAILURE(status)) {
@@ -1797,6 +1846,10 @@
 
     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 @@
     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 @@
     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 @@
 
         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 @@
     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 @@
         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 @@
     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 @@
     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 @@
         UBool sameRule = FALSE;
         const AnnualTimeZoneRule *atzrule;
         if (isDst) {
-            if (finalDstRule == NULL
-                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
+            if (finalDstRule == nullptr
+                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != nullptr
                 && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
             ) {
                 finalDstRule = atzrule->clone();
@@ -2000,12 +2057,12 @@
                 dstStartTime = dstUntilTime = t;
                 dstCount = 1;
             }
-            if (finalStdRule != NULL && finalDstRule != NULL) {
+            if (finalStdRule != nullptr && finalDstRule != nullptr) {
                 break;
             }
         } else {
-            if (finalStdRule == NULL
-                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != NULL
+            if (finalStdRule == nullptr
+                && (atzrule = dynamic_cast<const AnnualTimeZoneRule *>(tzt.getTo())) != nullptr
                 && atzrule->getEndYear() == AnnualTimeZoneRule::MAX_YEAR
             ) {
                 finalStdRule = atzrule->clone();
@@ -2051,7 +2108,7 @@
                 stdStartTime = stdUntilTime = t;
                 stdCount = 1;
             }
-            if (finalStdRule != NULL && finalDstRule != NULL) {
+            if (finalStdRule != nullptr && finalDstRule != nullptr) {
                 break;
             }
         }
@@ -2075,7 +2132,7 @@
         }
     } 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 @@
             }
         }
         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 @@
 
 cleanupWriteZone:
 
-    if (finalStdRule != NULL) {
+    if (finalStdRule != nullptr) {
         delete finalStdRule;
     }
-    if (finalDstRule != NULL) {
+    if (finalDstRule != nullptr) {
         delete finalDstRule;
     }
 }
@@ -2479,8 +2536,11 @@
         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();
     }