]> granicus.if.org Git - icu/commitdiff
ICU-13060 Additional Coverity fixes for DecimalFormat.
authorShane Carr <shane@unicode.org>
Fri, 24 Mar 2017 03:47:27 +0000 (03:47 +0000)
committerShane Carr <shane@unicode.org>
Fri, 24 Mar 2017 03:47:27 +0000 (03:47 +0000)
X-SVN-Rev: 39924

icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantity2.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantity3.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantity4.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/FormatQuantityBCD.java
icu4j/main/classes/core/src/com/ibm/icu/impl/number/modifiers/ConstantAffixModifier.java
icu4j/main/classes/core/src/com/ibm/icu/text/DecimalFormat.java

index 30931692d7fbaba9bac4597364a311d2e1920762..a423ef04227dc1655efcb000b88e9fb871f73616 100644 (file)
@@ -85,6 +85,7 @@ public final class FormatQuantity2 extends FormatQuantityBCD {
 
   @Override
   protected void readIntToBcd(int n) {
+    assert n != 0;
     long result = 0L;
     int i = 16;
     for (; n != 0; n /= 10, i--) {
@@ -98,6 +99,7 @@ public final class FormatQuantity2 extends FormatQuantityBCD {
 
   @Override
   protected void readLongToBcd(long n) {
+    assert n != 0;
     long result = 0L;
     int i = 16;
     for (; n != 0L; n /= 10L, i--) {
@@ -111,6 +113,7 @@ public final class FormatQuantity2 extends FormatQuantityBCD {
 
   @Override
   protected void readBigIntegerToBcd(BigInteger n) {
+    assert n.signum() != 0;
     long result = 0L;
     int i = 16;
     for (; n.signum() != 0; i--) {
index 9e25a45a74fabf085456198fc8d711dbba668786..5024f47a37c7e4f8d771d48033278ade55a76a2e 100644 (file)
@@ -99,6 +99,7 @@ public final class FormatQuantity3 extends FormatQuantityBCD {
 
   @Override
   protected void readIntToBcd(int n) {
+    assert n != 0;
     int i = 0;
     for (; n != 0L; n /= 10L, i++) {
       bcd[i] = (byte) (n % 10);
@@ -112,6 +113,7 @@ public final class FormatQuantity3 extends FormatQuantityBCD {
 
   @Override
   protected void readLongToBcd(long n) {
+    assert n != 0;
     if (n == Long.MIN_VALUE) {
       // Can't consume via the normal path.
       System.arraycopy(LONG_MIN_VALUE, 0, bcd, 0, LONG_MIN_VALUE.length);
@@ -129,6 +131,7 @@ public final class FormatQuantity3 extends FormatQuantityBCD {
 
   @Override
   protected void readBigIntegerToBcd(BigInteger n) {
+    assert n.signum() != 0;
     int i = 0;
     for (; n.signum() != 0; i++) {
       BigInteger[] temp = n.divideAndRemainder(BigInteger.TEN);
index 3307fff7e4f093e3ca6a7492d2fb4e43d26ec394..f22cca4613eed304ac8f834cdc9f1082da571285 100644 (file)
@@ -155,6 +155,7 @@ public final class FormatQuantity4 extends FormatQuantityBCD {
 
   @Override
   protected void readIntToBcd(int n) {
+    assert n != 0;
     // ints always fit inside the long implementation.
     long result = 0L;
     int i = 16;
@@ -169,6 +170,7 @@ public final class FormatQuantity4 extends FormatQuantityBCD {
 
   @Override
   protected void readLongToBcd(long n) {
+    assert n != 0;
     if (n >= 10000000000000000L) {
       ensureCapacity();
       int i = 0;
@@ -194,6 +196,7 @@ public final class FormatQuantity4 extends FormatQuantityBCD {
 
   @Override
   protected void readBigIntegerToBcd(BigInteger n) {
+    assert n.signum() != 0;
     ensureCapacity(); // allocate initial byte array
     int i = 0;
     for (; n.signum() != 0; i++) {
index a096c2c315f1d29122d49124b8b09c74b16e1ae3..67df9b17a15f951c1245370e342e257d57c31ae4 100644 (file)
@@ -457,8 +457,11 @@ public abstract class FormatQuantityBCD implements FormatQuantity {
       for (; i <= -22; i += 22) n /= 1e22;
       n /= DOUBLE_MULTIPLIERS[-i];
     }
-    _setToLong(Math.round(n));
-    scale -= fracLength;
+    long result = Math.round(n);
+    if (result != 0) {
+      _setToLong(result);
+      scale -= fracLength;
+    }
   }
 
   /**
index b133bc48723ed95b462cf8fa6485c27319c36554..2eea973956e78a4bf008c95ca7efb82824116f6a 100644 (file)
@@ -81,8 +81,8 @@ public class ConstantAffixModifier extends Modifier.BaseModifier implements Affi
   public boolean contentEquals(CharSequence _prefix, CharSequence _suffix) {
     if (_prefix == null && !prefix.isEmpty()) return false;
     if (_suffix == null && !suffix.isEmpty()) return false;
-    if (prefix.length() != _prefix.length()) return false;
-    if (suffix.length() != _suffix.length()) return false;
+    if (_prefix != null && prefix.length() != _prefix.length()) return false;
+    if (_suffix != null && suffix.length() != _suffix.length()) return false;
     for (int i = 0; i < prefix.length(); i++) {
       if (prefix.charAt(i) != _prefix.charAt(i)) return false;
     }
index 1fab6789e48a93310953d17e11677a4e55b1bf63..3a97615f027a37daaa5698d4d7b7f395e13cbd9b 100644 (file)
@@ -233,7 +233,7 @@ public class DecimalFormat extends NumberFormat {
    * Custom serialization: save property bag and symbols; the formatter object can be re-created
    * from just that amount of information.
    */
-  private void writeObject(ObjectOutputStream oos) throws IOException {
+  private synchronized void writeObject(ObjectOutputStream oos) throws IOException {
     // ICU 59 custom serialization.
     // Write class metadata and serialVersionOnStream field:
     oos.defaultWriteObject();
@@ -498,14 +498,6 @@ public class DecimalFormat extends NumberFormat {
     return result;
   }
 
-  private static final ThreadLocal<Properties> threadLocalCurrencyProperties =
-      new ThreadLocal<Properties>() {
-        @Override
-        protected Properties initialValue() {
-          return new Properties();
-        }
-      };
-
   /**
    * {@inheritDoc}
    *
@@ -515,7 +507,7 @@ public class DecimalFormat extends NumberFormat {
   public StringBuffer format(CurrencyAmount currAmt, StringBuffer toAppendTo, FieldPosition pos) {
     // TODO: This is ugly (although not as ugly as it was in ICU 58).
     // Currency should be a free parameter, not in property bag. Fix in ICU 60.
-    Properties cprops = threadLocalCurrencyProperties.get();
+    Properties cprops = threadLocalProperties.get();
     SingularFormat fmt = null;
     synchronized (this) {
       // Use the pre-compiled formatter if possible.  Otherwise, copy the properties
@@ -544,8 +536,12 @@ public class DecimalFormat extends NumberFormat {
    */
   @Override
   public Number parse(String text, ParsePosition parsePosition) {
+    Properties pprops = threadLocalProperties.get();
+    synchronized (this) {
+      pprops.copyFrom(properties);
+    }
     // Backwards compatibility: use currency parse mode if this is a currency instance
-    Number result = Parse.parse(text, parsePosition, properties, symbols);
+    Number result = Parse.parse(text, parsePosition, pprops, symbols);
     // Backwards compatibility: return com.ibm.icu.math.BigDecimal
     if (result instanceof java.math.BigDecimal) {
       result = new com.ibm.icu.math.BigDecimal((java.math.BigDecimal) result);
@@ -1711,7 +1707,7 @@ public class DecimalFormat extends NumberFormat {
    * @category Currency
    * @stable ICU 4.2
    */
-  public CurrencyPluralInfo getCurrencyPluralInfo() {
+  public synchronized CurrencyPluralInfo getCurrencyPluralInfo() {
     // CurrencyPluralInfo also is not exported.
     return properties.getCurrencyPluralInfo();
   }
@@ -1727,7 +1723,7 @@ public class DecimalFormat extends NumberFormat {
    * @category Currency
    * @stable ICU 4.2
    */
-  public void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
+  public synchronized void setCurrencyPluralInfo(CurrencyPluralInfo newInfo) {
     properties.setCurrencyPluralInfo(newInfo);
     refreshFormatter();
   }
@@ -1978,14 +1974,6 @@ public class DecimalFormat extends NumberFormat {
     return properties.hashCode();
   }
 
-  private static final ThreadLocal<Properties> threadLocalToPatternProperties =
-      new ThreadLocal<Properties>() {
-        @Override
-        protected Properties initialValue() {
-          return new Properties();
-        }
-      };
-
   /**
    * Returns the default value of toString() with extra DecimalFormat-specific information appended
    * to the end of the string. This extra information is intended for debugging purposes, and the
@@ -2027,8 +2015,7 @@ public class DecimalFormat extends NumberFormat {
     // to keep affix patterns intact.  In particular, pull rounding properties
     // so that CurrencyUsage is reflected properly.
     // TODO: Consider putting this logic in PatternString.java instead.
-    Properties tprops = threadLocalToPatternProperties.get();
-    tprops.copyFrom(properties);
+    Properties tprops = threadLocalProperties.get().copyFrom(properties);
     if (com.ibm.icu.impl.number.formatters.CurrencyFormat.useCurrency(properties)) {
       tprops.setMinimumFractionDigits(exportedProperties.getMinimumFractionDigits());
       tprops.setMaximumFractionDigits(exportedProperties.getMaximumFractionDigits());
@@ -2060,6 +2047,14 @@ public class DecimalFormat extends NumberFormat {
     return fq;
   }
 
+  private static final ThreadLocal<Properties> threadLocalProperties =
+      new ThreadLocal<Properties>() {
+        @Override
+        protected Properties initialValue() {
+          return new Properties();
+        }
+      };
+
   /** Rebuilds the formatter object from the property bag. */
   void refreshFormatter() {
     if (exportedProperties == null) {