]> granicus.if.org Git - icu/commitdiff
ICU-21174 Increase safety of Measure and writeAffixes.
authorHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Tue, 4 Aug 2020 02:49:23 +0000 (04:49 +0200)
committerHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Tue, 4 Aug 2020 23:52:40 +0000 (01:52 +0200)
Measure: initialize unit to nullptr, and don't dereference it if it is
nullptr.

NumberFormatterImpl::writeAffixes: U_ASSERT not-null, instead of
segfaulting for coding mistakes.

icu4c/source/i18n/measure.cpp
icu4c/source/i18n/number_formatimpl.cpp

index bffa44215e3cde31f7d01faba6230bd942eac266..23adba100707aa2338433a51664983987bb906e0 100644 (file)
@@ -23,7 +23,7 @@ U_NAMESPACE_BEGIN
 
 UOBJECT_DEFINE_RTTI_IMPLEMENTATION(Measure)
 
-Measure::Measure() {}
+Measure::Measure() : unit(nullptr) {}
 
 Measure::Measure(const Formattable& _number, MeasureUnit* adoptedUnit,
                  UErrorCode& ec) :
@@ -35,7 +35,7 @@ Measure::Measure(const Formattable& _number, MeasureUnit* adoptedUnit,
 }
 
 Measure::Measure(const Measure& other) :
-    UObject(other), unit(0) {
+    UObject(other), unit(nullptr) {
     *this = other;
 }
 
@@ -43,7 +43,11 @@ Measure& Measure::operator=(const Measure& other) {
     if (this != &other) {
         delete unit;
         number = other.number;
-        unit = other.unit->clone();
+        if (other.unit != nullptr) {
+            unit = other.unit->clone();
+        } else {
+            unit = nullptr;
+        }
     }
     return *this;
 }
index 5bba09cfb5293e0caf3696704f56f79e52330799..d5c3e6e4323696ec5cb4894d369e6e98af7afe36 100644 (file)
@@ -417,6 +417,7 @@ NumberFormatterImpl::resolvePluralRules(const PluralRules* rulesPtr, const Local
 
 int32_t NumberFormatterImpl::writeAffixes(const MicroProps& micros, FormattedStringBuilder& string,
                                           int32_t start, int32_t end, UErrorCode& status) {
+    U_ASSERT(micros.modOuter != nullptr);
     // Always apply the inner modifier (which is "strong").
     int32_t length = micros.modInner->apply(string, start, end, status);
     if (micros.padding.isValid()) {