From 5c8b142a92db6d602aacec6440b09b9a710b63c5 Mon Sep 17 00:00:00 2001 From: Jeff Genovy <29107334+jefgen@users.noreply.github.com> Date: Wed, 11 Mar 2020 01:33:27 -0700 Subject: [PATCH] ICU-21014 Fix OOM not checked in dtitvfmt.cpp and dtitvinf.cpp --- icu4c/source/i18n/dtitvfmt.cpp | 131 +++++++++++++++++++-------------- icu4c/source/i18n/dtitvinf.cpp | 62 +++++++++------- 2 files changed, 111 insertions(+), 82 deletions(-) diff --git a/icu4c/source/i18n/dtitvfmt.cpp b/icu4c/source/i18n/dtitvfmt.cpp index 64b4065292d..b71a571d1c4 100644 --- a/icu4c/source/i18n/dtitvfmt.cpp +++ b/icu4c/source/i18n/dtitvfmt.cpp @@ -108,6 +108,10 @@ DateIntervalFormat::createInstance(const UnicodeString& skeleton, #endif DateIntervalInfo* dtitvinf = new DateIntervalInfo(locale, status); + if (dtitvinf == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return nullptr; + } return create(locale, dtitvinf, &skeleton, status); } @@ -132,27 +136,27 @@ DateIntervalFormat::createInstance(const UnicodeString& skeleton, DateIntervalFormat::DateIntervalFormat() -: fInfo(NULL), - fDateFormat(NULL), - fFromCalendar(NULL), - fToCalendar(NULL), +: fInfo(nullptr), + fDateFormat(nullptr), + fFromCalendar(nullptr), + fToCalendar(nullptr), fLocale(Locale::getRoot()), - fDatePattern(NULL), - fTimePattern(NULL), - fDateTimeFormat(NULL) + fDatePattern(nullptr), + fTimePattern(nullptr), + fDateTimeFormat(nullptr) {} DateIntervalFormat::DateIntervalFormat(const DateIntervalFormat& itvfmt) : Format(itvfmt), - fInfo(NULL), - fDateFormat(NULL), - fFromCalendar(NULL), - fToCalendar(NULL), + fInfo(nullptr), + fDateFormat(nullptr), + fFromCalendar(nullptr), + fToCalendar(nullptr), fLocale(itvfmt.fLocale), - fDatePattern(NULL), - fTimePattern(NULL), - fDateTimeFormat(NULL) { + fDatePattern(nullptr), + fTimePattern(nullptr), + fDateTimeFormat(nullptr) { *this = itvfmt; } @@ -172,23 +176,23 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { if ( itvfmt.fDateFormat ) { fDateFormat = itvfmt.fDateFormat->clone(); } else { - fDateFormat = NULL; + fDateFormat = nullptr; } if ( itvfmt.fFromCalendar ) { fFromCalendar = itvfmt.fFromCalendar->clone(); } else { - fFromCalendar = NULL; + fFromCalendar = nullptr; } if ( itvfmt.fToCalendar ) { fToCalendar = itvfmt.fToCalendar->clone(); } else { - fToCalendar = NULL; + fToCalendar = nullptr; } } if ( itvfmt.fInfo ) { fInfo = itvfmt.fInfo->clone(); } else { - fInfo = NULL; + fInfo = nullptr; } fSkeleton = itvfmt.fSkeleton; int8_t i; @@ -196,9 +200,9 @@ DateIntervalFormat::operator=(const DateIntervalFormat& itvfmt) { fIntervalPatterns[i] = itvfmt.fIntervalPatterns[i]; } fLocale = itvfmt.fLocale; - fDatePattern = (itvfmt.fDatePattern)? itvfmt.fDatePattern->clone(): NULL; - fTimePattern = (itvfmt.fTimePattern)? itvfmt.fTimePattern->clone(): NULL; - fDateTimeFormat = (itvfmt.fDateTimeFormat)? itvfmt.fDateTimeFormat->clone(): NULL; + fDatePattern = (itvfmt.fDatePattern)? itvfmt.fDatePattern->clone(): nullptr; + fTimePattern = (itvfmt.fTimePattern)? itvfmt.fTimePattern->clone(): nullptr; + fDateTimeFormat = (itvfmt.fDateTimeFormat)? itvfmt.fDateTimeFormat->clone(): nullptr; } return *this; } @@ -227,21 +231,21 @@ DateIntervalFormat::operator==(const Format& other) const { const DateIntervalFormat* fmt = (DateIntervalFormat*)&other; if (this == fmt) {return TRUE;} if (!Format::operator==(other)) {return FALSE;} - if ((fInfo != fmt->fInfo) && (fInfo == NULL || fmt->fInfo == NULL)) {return FALSE;} + if ((fInfo != fmt->fInfo) && (fInfo == nullptr || fmt->fInfo == nullptr)) {return FALSE;} if (fInfo && fmt->fInfo && (*fInfo != *fmt->fInfo )) {return FALSE;} { Mutex lock(&gFormatterMutex); - if (fDateFormat != fmt->fDateFormat && (fDateFormat == NULL || fmt->fDateFormat == NULL)) {return FALSE;} + if (fDateFormat != fmt->fDateFormat && (fDateFormat == nullptr || fmt->fDateFormat == nullptr)) {return FALSE;} if (fDateFormat && fmt->fDateFormat && (*fDateFormat != *fmt->fDateFormat)) {return FALSE;} } // note: fFromCalendar and fToCalendar hold no persistent state, and therefore do not participate in operator ==. // fDateFormat has the master calendar for the DateIntervalFormat. if (fSkeleton != fmt->fSkeleton) {return FALSE;} - if (fDatePattern != fmt->fDatePattern && (fDatePattern == NULL || fmt->fDatePattern == NULL)) {return FALSE;} + if (fDatePattern != fmt->fDatePattern && (fDatePattern == nullptr || fmt->fDatePattern == nullptr)) {return FALSE;} if (fDatePattern && fmt->fDatePattern && (*fDatePattern != *fmt->fDatePattern)) {return FALSE;} - if (fTimePattern != fmt->fTimePattern && (fTimePattern == NULL || fmt->fTimePattern == NULL)) {return FALSE;} + if (fTimePattern != fmt->fTimePattern && (fTimePattern == nullptr || fmt->fTimePattern == nullptr)) {return FALSE;} if (fTimePattern && fmt->fTimePattern && (*fTimePattern != *fmt->fTimePattern)) {return FALSE;} - if (fDateTimeFormat != fmt->fDateTimeFormat && (fDateTimeFormat == NULL || fmt->fDateTimeFormat == NULL)) {return FALSE;} + if (fDateTimeFormat != fmt->fDateTimeFormat && (fDateTimeFormat == nullptr || fmt->fDateTimeFormat == nullptr)) {return FALSE;} if (fDateTimeFormat && fmt->fDateTimeFormat && (*fDateTimeFormat != *fmt->fDateTimeFormat)) {return FALSE;} if (fLocale != fmt->fLocale) {return FALSE;} @@ -266,7 +270,7 @@ DateIntervalFormat::format(const Formattable& obj, if ( obj.getType() == Formattable::kObject ) { const UObject* formatObj = obj.getObject(); const DateInterval* interval = dynamic_cast(formatObj); - if (interval != NULL) { + if (interval != nullptr) { return format(interval, appendTo, fieldPosition, status); } } @@ -283,7 +287,7 @@ DateIntervalFormat::format(const DateInterval* dtInterval, if ( U_FAILURE(status) ) { return appendTo; } - if (fDateFormat == NULL || fInfo == NULL) { + if (fDateFormat == nullptr || fInfo == nullptr) { status = U_INVALID_STATE_ERROR; return appendTo; } @@ -300,6 +304,10 @@ DateIntervalFormat::format(const DateInterval* dtInterval, FormattedDateInterval DateIntervalFormat::formatToValue( const DateInterval& dtInterval, UErrorCode& status) const { + if (U_FAILURE(status)) { + return FormattedDateInterval(status); + } + // LocalPointer only sets OOM status if U_SUCCESS is true. LocalPointer result(new FormattedDateIntervalData(status), status); if (U_FAILURE(status)) { return FormattedDateInterval(status); @@ -350,6 +358,10 @@ FormattedDateInterval DateIntervalFormat::formatToValue( Calendar& fromCalendar, Calendar& toCalendar, UErrorCode& status) const { + if (U_FAILURE(status)) { + return FormattedDateInterval(status); + } + // LocalPointer only sets OOM status if U_SUCCESS is true. LocalPointer result(new FormattedDateIntervalData(status), status); if (U_FAILURE(status)) { return FormattedDateInterval(status); @@ -540,14 +552,17 @@ DateIntervalFormat::setDateIntervalInfo(const DateIntervalInfo& newItvPattern, UErrorCode& status) { delete fInfo; fInfo = new DateIntervalInfo(newItvPattern); + if (fInfo == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + } // Delete patterns that get reset by initializePattern delete fDatePattern; - fDatePattern = NULL; + fDatePattern = nullptr; delete fTimePattern; - fTimePattern = NULL; + fTimePattern = nullptr; delete fDateTimeFormat; - fDateTimeFormat = NULL; + fDateTimeFormat = nullptr; if (fDateFormat) { initializePattern(status); @@ -565,7 +580,7 @@ DateIntervalFormat::getDateFormat() const { void DateIntervalFormat::adoptTimeZone(TimeZone* zone) { - if (fDateFormat != NULL) { + if (fDateFormat != nullptr) { fDateFormat->adoptTimeZone(zone); } // The fDateFormat has the master calendar for the DateIntervalFormat and has @@ -583,7 +598,7 @@ DateIntervalFormat::adoptTimeZone(TimeZone* zone) void DateIntervalFormat::setTimeZone(const TimeZone& zone) { - if (fDateFormat != NULL) { + if (fDateFormat != nullptr) { fDateFormat->setTimeZone(zone); } // The fDateFormat has the master calendar for the DateIntervalFormat; @@ -599,11 +614,11 @@ DateIntervalFormat::setTimeZone(const TimeZone& zone) const TimeZone& DateIntervalFormat::getTimeZone() const { - if (fDateFormat != NULL) { + if (fDateFormat != nullptr) { Mutex lock(&gFormatterMutex); return fDateFormat->getTimeZone(); } - // If fDateFormat is NULL (unexpected), create default timezone. + // If fDateFormat is nullptr (unexpected), create default timezone. return *(TimeZone::createDefault()); } @@ -611,14 +626,14 @@ DateIntervalFormat::DateIntervalFormat(const Locale& locale, DateIntervalInfo* dtItvInfo, const UnicodeString* skeleton, UErrorCode& status) -: fInfo(NULL), - fDateFormat(NULL), - fFromCalendar(NULL), - fToCalendar(NULL), +: fInfo(nullptr), + fDateFormat(nullptr), + fFromCalendar(nullptr), + fToCalendar(nullptr), fLocale(locale), - fDatePattern(NULL), - fTimePattern(NULL), - fDateTimeFormat(NULL) + fDatePattern(nullptr), + fTimePattern(nullptr), + fDateTimeFormat(nullptr) { LocalPointer info(dtItvInfo, status); LocalPointer dtfmt(static_cast( @@ -646,7 +661,7 @@ DateIntervalFormat::create(const Locale& locale, UErrorCode& status) { DateIntervalFormat* f = new DateIntervalFormat(locale, dtitvinf, skeleton, status); - if ( f == NULL ) { + if ( f == nullptr ) { status = U_MEMORY_ALLOCATION_ERROR; delete dtitvinf; } else if ( U_FAILURE(status) ) { @@ -763,7 +778,7 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { // with the time interval. // The date/time pattern ( such as {0} {1} ) is saved in // calendar, that is why need to get the CalendarData here. - LocalUResourceBundlePointer dateTimePatternsRes(ures_open(NULL, locale.getBaseName(), &status)); + LocalUResourceBundlePointer dateTimePatternsRes(ures_open(nullptr, locale.getBaseName(), &status)); ures_getByKey(dateTimePatternsRes.getAlias(), gCalendarTag, dateTimePatternsRes.getAlias(), &status); ures_getByKeyWithFallback(dateTimePatternsRes.getAlias(), gGregorianTag, @@ -778,6 +793,10 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { &dateTimeFormatLength, &status); if ( U_SUCCESS(status) && dateTimeFormatLength >= 3 ) { fDateTimeFormat = new UnicodeString(dateTimeFormat, dateTimeFormatLength); + if (fDateTimeFormat == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } } } @@ -801,9 +820,9 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { // the first part of the pattern is empty, // the second part of the pattern is the full-pattern // should be used in fall-back. - setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder()); - setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrder()); - setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_DATE, nullptr, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_MONTH, nullptr, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_YEAR, nullptr, &pattern, fInfo->getDefaultOrder()); } else { // TODO: fall back } @@ -827,9 +846,9 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { // the first part of the pattern is empty, // the second part of the pattern is the full-pattern // should be used in fall-back. - setPatternInfo(UCAL_DATE, NULL, &pattern, fInfo->getDefaultOrder()); - setPatternInfo(UCAL_MONTH, NULL, &pattern, fInfo->getDefaultOrder()); - setPatternInfo(UCAL_YEAR, NULL, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_DATE, nullptr, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_MONTH, nullptr, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(UCAL_YEAR, nullptr, &pattern, fInfo->getDefaultOrder()); } else { /* if both present, * 1) when the year, month, or day differs, @@ -864,7 +883,7 @@ DateIntervalFormat::initializePattern(UErrorCode& status) { * range expression for the time. */ - if ( fDateTimeFormat == NULL ) { + if ( fDateTimeFormat == nullptr ) { // earlier failure getting dateTimeFormat return; } @@ -1074,16 +1093,16 @@ DateIntervalFormat::setSeparateDateTimePtn( int8_t differenceInfo = 0; const UnicodeString* bestSkeleton = fInfo->getBestSkeleton(*skeleton, differenceInfo); - /* best skeleton could be NULL. + /* best skeleton could be nullptr. For example: in "ca" resource file, interval format is defined as following intervalFormats{ fallback{"{0} - {1}"} } there is no skeletons/interval patterns defined, - and the best skeleton match could be NULL + and the best skeleton match could be nullptr */ - if ( bestSkeleton == NULL ) { + if ( bestSkeleton == nullptr ) { return false; } @@ -1094,11 +1113,13 @@ DateIntervalFormat::setSeparateDateTimePtn( status = U_ZERO_ERROR; fDatePattern = new UnicodeString(DateFormat::getBestPattern( fLocale, dateSkeleton, status)); + // no way to report OOM. :( } if ( timeSkeleton.length() != 0) { status = U_ZERO_ERROR; fTimePattern = new UnicodeString(DateFormat::getBestPattern( fLocale, timeSkeleton, status)); + // no way to report OOM. :( } // difference: @@ -1154,7 +1175,7 @@ DateIntervalFormat::setFallbackPattern(UCalendarDateFields field, if ( U_FAILURE(status) ) { return; } - setPatternInfo(field, NULL, &pattern, fInfo->getDefaultOrder()); + setPatternInfo(field, nullptr, &pattern, fInfo->getDefaultOrder()); } diff --git a/icu4c/source/i18n/dtitvinf.cpp b/icu4c/source/i18n/dtitvinf.cpp index b263765c066..25536346ec7 100644 --- a/icu4c/source/i18n/dtitvinf.cpp +++ b/icu4c/source/i18n/dtitvinf.cpp @@ -66,7 +66,7 @@ static const UChar gDefaultFallbackPattern[] = {LEFT_CURLY_BRACKET, DIGIT_ZERO, DateIntervalInfo::DateIntervalInfo(UErrorCode& status) : fFallbackIntervalPattern(gDefaultFallbackPattern), fFirstDateInPtnIsLaterDate(false), - fIntervalPatterns(NULL) + fIntervalPatterns(nullptr) { fIntervalPatterns = initHash(status); } @@ -76,7 +76,7 @@ DateIntervalInfo::DateIntervalInfo(UErrorCode& status) DateIntervalInfo::DateIntervalInfo(const Locale& locale, UErrorCode& status) : fFallbackIntervalPattern(gDefaultFallbackPattern), fFirstDateInPtnIsLaterDate(false), - fIntervalPatterns(NULL) + fIntervalPatterns(nullptr) { initializeData(locale, status); } @@ -126,7 +126,7 @@ DateIntervalInfo::setFallbackIntervalPattern( DateIntervalInfo::DateIntervalInfo(const DateIntervalInfo& dtitvinf) : UObject(dtitvinf), - fIntervalPatterns(NULL) + fIntervalPatterns(nullptr) { *this = dtitvinf; } @@ -161,7 +161,7 @@ DateIntervalInfo::clone() const { DateIntervalInfo::~DateIntervalInfo() { deleteHash(fIntervalPatterns); - fIntervalPatterns = NULL; + fIntervalPatterns = nullptr; } @@ -189,7 +189,7 @@ DateIntervalInfo::getIntervalPattern(const UnicodeString& skeleton, } const UnicodeString* patternsOfOneSkeleton = (UnicodeString*) fIntervalPatterns->get(skeleton); - if ( patternsOfOneSkeleton != NULL ) { + if ( patternsOfOneSkeleton != nullptr ) { IntervalPatternIndex index = calendarFieldToIntervalIndex(field, status); if ( U_FAILURE(status) ) { return result; @@ -363,7 +363,7 @@ struct DateIntervalInfo::DateIntervalSink : public ResourceSink { UnicodeString* patternsOfOneSkeleton = (UnicodeString*)(dateIntervalInfo.fIntervalPatterns->get(skeleton)); - if (patternsOfOneSkeleton == NULL || patternsOfOneSkeleton[index].isEmpty()) { + if (patternsOfOneSkeleton == nullptr || patternsOfOneSkeleton[index].isEmpty()) { UnicodeString pattern = value.getUnicodeString(errorCode); dateIntervalInfo.setIntervalPatternInternally(skeleton, lrgDiffCalUnit, pattern, errorCode); @@ -398,8 +398,8 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) char calendarType[ULOC_KEYWORDS_CAPACITY]; // to be filled in with the type to use, if all goes well char localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY]; // obtain a locale that always has the calendar key value that should be used - (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, NULL, - "calendar", "calendar", locName, NULL, FALSE, &status); + (void)ures_getFunctionalEquivalent(localeWithCalendarKey, ULOC_LOCALE_IDENTIFIER_CAPACITY, nullptr, + "calendar", "calendar", locName, nullptr, FALSE, &status); localeWithCalendarKey[ULOC_LOCALE_IDENTIFIER_CAPACITY-1] = 0; // ensure null termination // now get the calendar key value from that locale int32_t calendarTypeLen = uloc_getKeywordValue(localeWithCalendarKey, "calendar", calendarType, @@ -411,11 +411,11 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) // Instantiate the resource bundles UResourceBundle *rb, *calBundle; - rb = ures_open(NULL, locName, &status); + rb = ures_open(nullptr, locName, &status); if (U_FAILURE(status)) { return; } - calBundle = ures_getByKeyWithFallback(rb, gCalendarTag, NULL, &status); + calBundle = ures_getByKeyWithFallback(rb, gCalendarTag, nullptr, &status); if (U_SUCCESS(status)) { @@ -424,9 +424,9 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) // Get the fallback pattern const UChar* resStr = nullptr; int32_t resStrLen = 0; - calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, NULL, &status); + calTypeBundle = ures_getByKeyWithFallback(calBundle, calendarTypeToUse, nullptr, &status); itvDtPtnResource = ures_getByKeyWithFallback(calTypeBundle, - gIntervalDateTimePatternTag, NULL, &status); + gIntervalDateTimePatternTag, nullptr, &status); // TODO(ICU-20400): After the fixing, we should find the "fallback" from // the rb directly by the path "calendar/${calendar}/intervalFormats/fallback". if ( U_SUCCESS(status) ) { @@ -437,10 +437,10 @@ DateIntervalInfo::initializeData(const Locale& locale, UErrorCode& status) // ures_getByKeyWithFallback UErrorCode localStatus = U_ZERO_ERROR; UResourceBundle *genericCalBundle = - ures_getByKeyWithFallback(calBundle, gGenericTag, NULL, &localStatus); + ures_getByKeyWithFallback(calBundle, gGenericTag, nullptr, &localStatus); UResourceBundle *genericItvDtPtnResource = ures_getByKeyWithFallback( - genericCalBundle, gIntervalDateTimePatternTag, NULL, &localStatus); + genericCalBundle, gIntervalDateTimePatternTag, nullptr, &localStatus); resStr = ures_getStringByKeyWithFallback( genericItvDtPtnResource, gFallbackPatternTag, &resStrLen, &localStatus); ures_close(genericItvDtPtnResource); @@ -509,8 +509,12 @@ DateIntervalInfo::setIntervalPatternInternally(const UnicodeString& skeleton, } UnicodeString* patternsOfOneSkeleton = (UnicodeString*)(fIntervalPatterns->get(skeleton)); UBool emptyHash = false; - if ( patternsOfOneSkeleton == NULL ) { + if ( patternsOfOneSkeleton == nullptr ) { patternsOfOneSkeleton = new UnicodeString[kIPI_MAX_INDEX]; + if (patternsOfOneSkeleton == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } emptyHash = true; } @@ -608,7 +612,7 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, parseSkeleton(*inputSkeleton, inputSkeletonFieldWidth); int32_t bestDistance = MAX_POSITIVE_INT; - const UnicodeString* bestSkeleton = NULL; + const UnicodeString* bestSkeleton = nullptr; // 0 means exact the same skeletons; // 1 means having the same field, but with different length, @@ -618,8 +622,8 @@ DateIntervalInfo::getBestSkeleton(const UnicodeString& skeleton, int8_t fieldLength = UPRV_LENGTHOF(skeletonFieldWidth); int32_t pos = UHASH_FIRST; - const UHashElement* elem = NULL; - while ( (elem = fIntervalPatterns->nextElement(pos)) != NULL ) { + const UHashElement* elem = nullptr; + while ( (elem = fIntervalPatterns->nextElement(pos)) != nullptr ) { const UHashTok keyTok = elem->key; UnicodeString* newSkeleton = (UnicodeString*)keyTok.pointer; #ifdef DTITVINF_DEBUG @@ -725,12 +729,12 @@ DateIntervalInfo::calendarFieldToIntervalIndex(UCalendarDateFields field, void DateIntervalInfo::deleteHash(Hashtable* hTable) { - if ( hTable == NULL ) { + if ( hTable == nullptr ) { return; } int32_t pos = UHASH_FIRST; - const UHashElement* element = NULL; - while ( (element = hTable->nextElement(pos)) != NULL ) { + const UHashElement* element = nullptr; + while ( (element = hTable->nextElement(pos)) != nullptr ) { const UHashTok valueTok = element->value; const UnicodeString* value = (UnicodeString*)valueTok.pointer; delete[] value; @@ -768,16 +772,16 @@ U_CDECL_END Hashtable* DateIntervalInfo::initHash(UErrorCode& status) { if ( U_FAILURE(status) ) { - return NULL; + return nullptr; } Hashtable* hTable; - if ( (hTable = new Hashtable(FALSE, status)) == NULL ) { + if ( (hTable = new Hashtable(FALSE, status)) == nullptr ) { status = U_MEMORY_ALLOCATION_ERROR; - return NULL; + return nullptr; } if ( U_FAILURE(status) ) { delete hTable; - return NULL; + return nullptr; } hTable->setValueComparator(dtitvinfHashTableValueComparator); return hTable; @@ -792,14 +796,18 @@ DateIntervalInfo::copyHash(const Hashtable* source, return; } int32_t pos = UHASH_FIRST; - const UHashElement* element = NULL; + const UHashElement* element = nullptr; if ( source ) { - while ( (element = source->nextElement(pos)) != NULL ) { + while ( (element = source->nextElement(pos)) != nullptr ) { const UHashTok keyTok = element->key; const UnicodeString* key = (UnicodeString*)keyTok.pointer; const UHashTok valueTok = element->value; const UnicodeString* value = (UnicodeString*)valueTok.pointer; UnicodeString* copy = new UnicodeString[kIPI_MAX_INDEX]; + if (copy == nullptr) { + status = U_MEMORY_ALLOCATION_ERROR; + return; + } int8_t i; for ( i = 0; i < kIPI_MAX_INDEX; ++i ) { copy[i] = value[i]; -- 2.40.0