ICU-22817 Fix memory leak in basictz by using LocalPointer

See https://github.com/LuMingYinDetect/icu_defects/blob/main/icu_1.png
This commit is contained in:
Frank Tang 2025-03-17 21:41:05 -07:00 committed by Frank Yung-Fong Tang
parent 545bf260e1
commit cdf52396dc

View file

@ -140,8 +140,8 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
int32_t initialRaw, initialDst;
UnicodeString initialName;
AnnualTimeZoneRule *ar1 = nullptr;
AnnualTimeZoneRule *ar2 = nullptr;
LocalPointer<AnnualTimeZoneRule> ar1;
LocalPointer<AnnualTimeZoneRule> ar2;
UnicodeString name;
UBool avail;
@ -179,8 +179,8 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
// zone to return wrong offset after the transition.
// When we encounter such case, we do not inspect next next
// transition for another rule.
ar1 = new AnnualTimeZoneRule(name, initialRaw, tr.getTo()->getDSTSavings(),
dtr, year, AnnualTimeZoneRule::MAX_YEAR);
ar1.adoptInstead(new AnnualTimeZoneRule(name, initialRaw, tr.getTo()->getDSTSavings(),
dtr, year, AnnualTimeZoneRule::MAX_YEAR));
if (tr.getTo()->getRawOffset() == initialRaw) {
// Get the next next transition
@ -200,8 +200,8 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
// Generate another DOW rule
dtr = new DateTimeRule(month, weekInMonth, dow, mid, DateTimeRule::WALL_TIME);
tr.getTo()->getName(name);
ar2 = new AnnualTimeZoneRule(name, tr.getTo()->getRawOffset(), tr.getTo()->getDSTSavings(),
dtr, year - 1, AnnualTimeZoneRule::MAX_YEAR);
ar2.adoptInstead(new AnnualTimeZoneRule(name, tr.getTo()->getRawOffset(), tr.getTo()->getDSTSavings(),
dtr, year - 1, AnnualTimeZoneRule::MAX_YEAR));
// Make sure this rule can be applied to the specified date
avail = ar2->getPreviousStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), true, d);
@ -209,13 +209,12 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
|| initialRaw != tr.getTo()->getRawOffset()
|| initialDst != tr.getTo()->getDSTSavings()) {
// We cannot use this rule as the second transition rule
delete ar2;
ar2 = nullptr;
ar2.adoptInstead(nullptr);
}
}
}
}
if (ar2 == nullptr) {
if (ar2.isNull()) {
// Try previous transition
avail = getPreviousTransition(date, true, tr);
if (avail) {
@ -234,23 +233,21 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
// second rule raw/dst offsets should match raw/dst offsets
// at the given time
ar2 = new AnnualTimeZoneRule(name, initialRaw, initialDst,
dtr, ar1->getStartYear() - 1, AnnualTimeZoneRule::MAX_YEAR);
ar2.adoptInstead(new AnnualTimeZoneRule(name, initialRaw, initialDst,
dtr, ar1->getStartYear() - 1, AnnualTimeZoneRule::MAX_YEAR));
// Check if this rule start after the first rule after the specified date
avail = ar2->getNextStart(date, tr.getFrom()->getRawOffset(), tr.getFrom()->getDSTSavings(), false, d);
if (!avail || d <= nextTransitionTime) {
// We cannot use this rule as the second transition rule
delete ar2;
ar2 = nullptr;
ar2.adoptInstead(nullptr);
}
}
}
}
if (ar2 == nullptr) {
if (ar2.isNull()) {
// Cannot find a good pair of AnnualTimeZoneRule
delete ar1;
ar1 = nullptr;
ar1.adoptInstead(nullptr);
} else {
// The initial rule should represent the rule before the previous transition
ar1->getName(initialName);
@ -278,13 +275,13 @@ BasicTimeZone::getSimpleRulesNear(UDate date, InitialTimeZoneRule*& initial,
initial = new InitialTimeZoneRule(initialName, initialRaw, initialDst);
// Set the standard and daylight saving rules
if (ar1 != nullptr && ar2 != nullptr) {
if (ar1.isValid() && ar2.isValid()) {
if (ar1->getDSTSavings() != 0) {
dst = ar1;
std = ar2;
dst = ar1.orphan();
std = ar2.orphan();
} else {
std = ar1;
dst = ar2;
std = ar1.orphan();
dst = ar2.orphan();
}
}
}