]> granicus.if.org Git - icu/commitdiff
ICU-20079 integer overflow & divide by zero sanitizer fixes. (#67)
authorAndy Heninger <andy.heninger@gmail.com>
Mon, 20 Aug 2018 23:40:46 +0000 (16:40 -0700)
committerShane Carr <shane@unicode.org>
Thu, 27 Sep 2018 21:27:38 +0000 (14:27 -0700)
icu4c/source/common/bytestriebuilder.cpp
icu4c/source/common/uniset.cpp
icu4c/source/common/usprep.cpp
icu4c/source/io/ufmt_cmn.cpp
icu4c/source/test/intltest/numrgts.cpp
icu4c/source/test/iotest/iotest.cpp

index 581505e0092b15525bc1966b9cb3a039912e4b10..ec1ab7d8f5080e5af15799fa8636d3ab98b0ec73 100644 (file)
@@ -339,7 +339,8 @@ BytesTrieBuilder::indexOfElementWithNextUnit(int32_t i, int32_t byteIndex, UChar
 
 BytesTrieBuilder::BTLinearMatchNode::BTLinearMatchNode(const char *bytes, int32_t len, Node *nextNode)
         : LinearMatchNode(len, nextNode), s(bytes) {
-    hash=hash*37+ustr_hashCharsN(bytes, len);
+    hash=static_cast<int32_t>(
+        static_cast<uint32_t>(hash)*37u + static_cast<uint32_t>(ustr_hashCharsN(bytes, len)));
 }
 
 UBool
index 74a9efe47d7b8fcda092472bfd24d629e5a1aa43..7206e63e8873a3ee0864efcd2fd35678b38237ab 100644 (file)
@@ -364,12 +364,12 @@ UBool UnicodeSet::operator==(const UnicodeSet& o) const {
  * @see Object#hashCode()
  */
 int32_t UnicodeSet::hashCode(void) const {
-    int32_t result = len;
+    uint32_t result = static_cast<uint32_t>(len);
     for (int32_t i = 0; i < len; ++i) {
-        result *= 1000003;
+        result *= 1000003u;
         result += list[i];
     }
-    return result;
+    return static_cast<int32_t>(result);
 }
 
 //----------------------------------------------------------------
index 1af1d07490a9bc3aa8a4bc582e020a2d210bed42..01238b35f5bb06775373d6752d730d55a4823cd0 100644 (file)
@@ -112,7 +112,9 @@ hashEntry(const UHashTok parm) {
     UHashTok namekey, pathkey;
     namekey.pointer = b->name;
     pathkey.pointer = b->path;
-    return uhash_hashChars(namekey)+37*uhash_hashChars(pathkey);
+    uint32_t unsignedHash = static_cast<uint32_t>(uhash_hashChars(namekey)) +
+            37u * static_cast<uint32_t>(uhash_hashChars(pathkey));
+    return static_cast<int32_t>(unsignedHash);
 }
 
 /* compares two entries */
index 2b1a76fc8a2984426f0443bd4c341ea288d29361..c539729b87abf9973b7d1fe8e0642ff8552511f5 100644 (file)
@@ -140,7 +140,7 @@ ufmt_uto64(const UChar     *buffer,
 {
     const UChar     *limit;
     int32_t         count;
-    int64_t        result;
+    uint64_t        result;
     
     
     /* intialize parameters */
@@ -160,7 +160,7 @@ ufmt_uto64(const UChar     *buffer,
     }
     
     *len = count;
-    return result;
+    return static_cast<int64_t>(result);
 }
 
 #define NIBBLE_PER_BYTE 2
index 482704537d47295601f43ed46b07f16839570058..1870765ae8794ae38f5260b9e94e4497b67d49aa 100644 (file)
@@ -11,6 +11,7 @@
 
 #include "numrgts.h"
 
+#include <cmath>   // std::signbit
 #include <float.h> // DBL_MIN, DBL_MAX
 #include <stdio.h>
 
@@ -2142,8 +2143,9 @@ NumberFormatRegressionTest::Test4162852(void)
 {
     UErrorCode status = U_ZERO_ERROR;
     for(int32_t i=0; i < 2; ++i) {
-        NumberFormat *f = (i == 0) ? NumberFormat::createInstance(status)
-            : NumberFormat::createPercentInstance(status);
+        LocalPointer<NumberFormat> f(
+            ((i == 0) ? NumberFormat::createInstance(status) : NumberFormat::createPercentInstance(status)),
+            status);
         if(U_FAILURE(status)) {
             dataerrln("Couldn't create number format - %s", u_errorName(status));
             return;
@@ -2154,20 +2156,19 @@ NumberFormatRegressionTest::Test4162852(void)
         f->format(d, s);
         Formattable n;
         f->parse(s, n, status);
-        if(U_FAILURE(status))
+        if(U_FAILURE(status)) {
             errln("Couldn't parse!");
+            return;
+        }
         double e = n.getDouble();
-        logln(UnicodeString("") +
-              d + " -> " +
-              '"' + s + '"' + " -> " + e);
+        logln("%f -> \"%s\" -> %f", d, CStr(s)(), e);
 #if (U_PLATFORM == U_PF_OS390 && !defined(IEEE_754)) || U_PLATFORM == U_PF_OS400
         if (e != 0.0) {
 #else
-        if (e != 0.0 || 1.0/e > 0.0) {
+        if (e != 0.0 || (std::signbit(e) == false)) {
 #endif
-            logln("Failed to parse negative zero");
+            errln("Failed to parse negative zero");
         }
-        delete f;
     }
 }
 
index 6bc549ad4dae2f87ed6babd634a85f9cfcdced1a..186d10e17e5182b18e01415ea1b0dd32e1db9782 100644 (file)
@@ -178,18 +178,18 @@ char* DataDrivenLogger::fgTestDataPath = NULL;
 static int64_t
 uto64(const UChar     *buffer)
 {
-    int64_t result = 0;
+    uint64_t result = 0;
     /* iterate through buffer */
     while(*buffer) {
         /* read the next digit */
-        result *= 16;
+        result *= 16u;
         if (!u_isxdigit(*buffer)) {
             log_err("\\u%04X is not a valid hex digit for this test\n", (UChar)*buffer);
         }
         result += *buffer - 0x0030 - (*buffer >= 0x0041 ? (*buffer >= 0x0061 ? 39 : 7) : 0);
         buffer++;
     }
-    return result;
+    return (int64_t)result;
 }
 #endif