]> granicus.if.org Git - icu/commitdiff
ICU-21613 Fix undefined behaviour in ComplexUnitsConverter::applyRounder
authorHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Mon, 29 Nov 2021 23:23:30 +0000 (00:23 +0100)
committerHugo van der Merwe <17109322+hugovdm@users.noreply.github.com>
Tue, 30 Nov 2021 10:26:37 +0000 (11:26 +0100)
icu4c/source/i18n/units_complexconverter.cpp

index 78cefbf7ebb7333abf7658756ef4da62ba14c2f9..ecbe3c787941a7a47e68cf4dcf2a0068b23454db 100644 (file)
@@ -183,7 +183,7 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
             } else {
                 quantity = remainder;
             }
-        }   
+        }
     }
 
     applyRounder(intValues, quantity, rounder, status);
@@ -210,7 +210,6 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
         }
     }
 
-
     // Transfer values into result and return:
     for(int32_t i = 0, n = unitsConverters_.length(); i < n; ++i) {
         U_ASSERT(tmpResult[i] != nullptr);
@@ -224,6 +223,12 @@ MaybeStackVector<Measure> ComplexUnitsConverter::convert(double quantity,
 void ComplexUnitsConverter::applyRounder(MaybeStackArray<int64_t, 5> &intValues, double &quantity,
                                          icu::number::impl::RoundingImpl *rounder,
                                          UErrorCode &status) const {
+    if (uprv_isInfinite(quantity) || uprv_isNaN(quantity)) {
+        // Inf and NaN can't be rounded, and calculating `carry` below is known
+        // to fail on Gentoo on HPPA and OpenSUSE on riscv64. Nothing to do.
+        return;
+    }
+
     if (rounder == nullptr) {
         // Nothing to do for the quantity.
         return;