You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ki...@apache.org on 2019/12/08 23:29:51 UTC

svn commit: r1871064 - in /poi/trunk/src: examples/src/org/apache/poi/ss/examples/ java/org/apache/poi/hssf/record/ java/org/apache/poi/hssf/usermodel/ java/org/apache/poi/poifs/crypt/ java/org/apache/poi/poifs/crypt/cryptoapi/ java/org/apache/poi/poif...

Author: kiwiwings
Date: Sun Dec  8 23:29:50 2019
New Revision: 1871064

URL: http://svn.apache.org/viewvc?rev=1871064&view=rev
Log:
Sonar fixes - type: bugs / severity: major

Modified:
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java
    poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java
    poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java
    poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java
    poi/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed.java
    poi/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java
    poi/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java
    poi/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java
    poi/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java
    poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java

Modified: poi/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java (original)
+++ poi/trunk/src/examples/src/org/apache/poi/ss/examples/AddDimensionedImage.java Sun Dec  8 23:29:50 2019
@@ -685,8 +685,8 @@ public class AddDimensionedImage {
             if(sheet instanceof HSSFSheet) {
                 // Next, from the columns width, calculate how many co-ordinate
                 // positons there are per millimetre
-                coordinatePositionsPerMM = ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS /
-                    colWidthMM;
+                coordinatePositionsPerMM = (colWidthMM == 0) ? 0
+                    : ConvertImageUnits.TOTAL_COLUMN_COORDINATE_POSITIONS / colWidthMM;
                 // From this figure, determine how many co-ordinat positions to
                 // inset the left hand or bottom edge of the image.
                 inset = (int)(coordinatePositionsPerMM * overlapMM);
@@ -784,8 +784,8 @@ public class AddDimensionedImage {
             }
 
             if(sheet instanceof HSSFSheet) {
-                rowCoordinatesPerMM = ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS /
-                    rowHeightMM;
+                rowCoordinatesPerMM = (rowHeightMM == 0) ? 0
+                    : ConvertImageUnits.TOTAL_ROW_COORDINATE_POSITIONS / rowHeightMM;
                 inset = (int)(overlapMM * rowCoordinatesPerMM);
             }
             else {

Modified: poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java (original)
+++ poi/trunk/src/examples/src/org/apache/poi/ss/examples/BusinessPlan.java Sun Dec  8 23:29:50 2019
@@ -17,15 +17,26 @@
 
 package org.apache.poi.ss.examples;
 
-import org.apache.poi.xssf.usermodel.*;
-import org.apache.poi.ss.usermodel.*;
-import org.apache.poi.hssf.usermodel.HSSFWorkbook;
-
-import java.util.Map;
-import java.util.HashMap;
-import java.util.Calendar;
 import java.io.FileOutputStream;
 import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.poi.hssf.usermodel.HSSFWorkbook;
+import org.apache.poi.ss.usermodel.BorderStyle;
+import org.apache.poi.ss.usermodel.Cell;
+import org.apache.poi.ss.usermodel.CellStyle;
+import org.apache.poi.ss.usermodel.DataFormat;
+import org.apache.poi.ss.usermodel.FillPatternType;
+import org.apache.poi.ss.usermodel.Font;
+import org.apache.poi.ss.usermodel.HorizontalAlignment;
+import org.apache.poi.ss.usermodel.IndexedColors;
+import org.apache.poi.ss.usermodel.PrintSetup;
+import org.apache.poi.ss.usermodel.Row;
+import org.apache.poi.ss.usermodel.Sheet;
+import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.xssf.usermodel.XSSFWorkbook;
 
 /**
  * A business plan demo
@@ -36,8 +47,6 @@ import java.text.SimpleDateFormat;
  */
 public class BusinessPlan {
 
-    private static SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM");
-
     private static final String[] titles = {
             "ID", "Project Name", "Owner", "Days", "Start", "End"};
 
@@ -84,6 +93,8 @@ public class BusinessPlan {
         if(args.length > 0 && args[0].equals("-xls")) wb = new HSSFWorkbook();
         else wb = new XSSFWorkbook();
 
+        final SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM");
+
         Map<String, CellStyle> styles = createStyles(wb);
 
         Sheet sheet = wb.createSheet("Business Plan");
@@ -201,7 +212,7 @@ public class BusinessPlan {
         FileOutputStream out = new FileOutputStream(file);
         wb.write(out);
         out.close();
-        
+
         wb.close();
     }
 
@@ -315,7 +326,7 @@ public class BusinessPlan {
     private static CellStyle createBorderedStyle(Workbook wb){
         BorderStyle thin = BorderStyle.THIN;
         short black = IndexedColors.BLACK.getIndex();
-        
+
         CellStyle style = wb.createCellStyle();
         style.setBorderRight(thin);
         style.setRightBorderColor(black);

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FontRecord.java Sun Dec  8 23:29:50 2019
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record;
 
+import java.util.Objects;
+
 import org.apache.poi.util.BitField;
 import org.apache.poi.util.BitFieldFactory;
 import org.apache.poi.util.HexDump;
@@ -30,7 +32,8 @@ import org.apache.poi.util.StringUtil;
  * REFERENCE:  PG 315 Microsoft Excel 97 Developer's Kit (ISBN: 1-57231-498-2)
  */
 public final class FontRecord extends StandardRecord {
-	public final static short     sid                 = 0x0031;                                                 // docs are wrong (0x231 Microsoft Support site article Q184647)
+	// docs are wrong (0x231 Microsoft Support site article Q184647)
+	public final static short     sid                 = 0x0031;
 	public final static short     SS_NONE             = 0;
 	public final static short     SS_SUPER            = 1;
 	public final static short     SS_SUB              = 2;
@@ -39,7 +42,8 @@ public final class FontRecord extends St
 	public final static byte      U_DOUBLE            = 2;
 	public final static byte      U_SINGLE_ACCOUNTING = 0x21;
 	public final static byte      U_DOUBLE_ACCOUNTING = 0x22;
-	private short                 field_1_font_height;        // in units of .05 of a point
+	// in units of .05 of a point
+	private short                 field_1_font_height;
 	private short                 field_2_attributes;
 
 	// 0 0x01 - Reserved bit must be 0
@@ -359,24 +363,22 @@ public final class FontRecord extends St
 	}
 
 	public String toString() {
-		StringBuilder sb = new StringBuilder();
-
-		sb.append("[FONT]\n");
-		sb.append("    .fontheight    = ").append(HexDump.shortToHex(getFontHeight())).append("\n");
-		sb.append("    .attributes    = ").append(HexDump.shortToHex(getAttributes())).append("\n");
-		sb.append("       .italic     = ").append(isItalic()).append("\n");
-		sb.append("       .strikout   = ").append(isStruckout()).append("\n");
-		sb.append("       .macoutlined= ").append(isMacoutlined()).append("\n");
-		sb.append("       .macshadowed= ").append(isMacshadowed()).append("\n");
-		sb.append("    .colorpalette  = ").append(HexDump.shortToHex(getColorPaletteIndex())).append("\n");
-		sb.append("    .boldweight    = ").append(HexDump.shortToHex(getBoldWeight())).append("\n");
-		sb.append("    .supersubscript= ").append(HexDump.shortToHex(getSuperSubScript())).append("\n");
-		sb.append("    .underline     = ").append(HexDump.byteToHex(getUnderline())).append("\n");
-		sb.append("    .family        = ").append(HexDump.byteToHex(getFamily())).append("\n");
-		sb.append("    .charset       = ").append(HexDump.byteToHex(getCharset())).append("\n");
-		sb.append("    .fontname      = ").append(getFontName()).append("\n");
-		sb.append("[/FONT]\n");
-		return sb.toString();
+		return
+			"[FONT]\n" +
+			"    .fontheight    = " + HexDump.shortToHex(getFontHeight()) + "\n" +
+			"    .attributes    = " + HexDump.shortToHex(getAttributes()) + "\n" +
+			"       .italic     = " + isItalic() + "\n" +
+			"       .strikout   = " + isStruckout() + "\n" +
+			"       .macoutlined= " + isMacoutlined() + "\n" +
+			"       .macshadowed= " + isMacshadowed() + "\n" +
+			"    .colorpalette  = " + HexDump.shortToHex(getColorPaletteIndex()) + "\n" +
+			"    .boldweight    = " + HexDump.shortToHex(getBoldWeight()) + "\n" +
+			"    .supersubscript= " + HexDump.shortToHex(getSuperSubScript()) + "\n" +
+			"    .underline     = " + HexDump.byteToHex(getUnderline()) + "\n" +
+			"    .family        = " + HexDump.byteToHex(getFamily()) + "\n" +
+			"    .charset       = " + HexDump.byteToHex(getCharset()) + "\n" +
+			"    .fontname      = " + getFontName() + "\n" +
+			"[/FONT]\n";
 	}
 
 	public void serialize(LittleEndianOutput out) {
@@ -421,7 +423,7 @@ public final class FontRecord extends St
 	 * Clones all the font style information from another
 	 *  FontRecord, onto this one. This
 	 *  will then hold all the same font style options.
-	 * 
+	 *
 	 * @param source the record to clone the properties from
 	 */
 	public void cloneStyleFrom(FontRecord source) {
@@ -464,12 +466,13 @@ public final class FontRecord extends St
 	 *  for exact contents, because normally the
 	 *  font record's position makes a big
 	 *  difference too.
-	 *  
+	 *
 	 *  @param other the record to compare with
-	 *  
+	 *
 	 *  @return true, if the properties match
 	 */
 	public boolean sameProperties(FontRecord other) {
+
 		return
 		field_1_font_height         == other.field_1_font_height &&
 		field_2_attributes          == other.field_2_attributes &&
@@ -480,15 +483,11 @@ public final class FontRecord extends St
 		field_7_family              == other.field_7_family &&
 		field_8_charset             == other.field_8_charset &&
 		field_9_zero                == other.field_9_zero &&
-        stringEquals(this.field_11_font_name, other.field_11_font_name)
+		Objects.equals(this.field_11_font_name, other.field_11_font_name)
 		;
 	}
 
     public boolean equals(Object o) {
-        return (o instanceof FontRecord) ? sameProperties((FontRecord)o) : false;
-    }
-    
-    private static boolean stringEquals(String s1, String s2) {
-        return (s1 == s2 || (s1 != null && s1.equals(s2)));
+        return (o instanceof FontRecord) && sameProperties((FontRecord) o);
     }
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/usermodel/HSSFCellStyle.java Sun Dec  8 23:29:50 2019
@@ -108,7 +108,7 @@ public final class HSSFCellStyle impleme
     }
 
     // we keep the cached data in ThreadLocal members in order to
-    // avoid multi-threading issues when different workbooks are accessed in 
+    // avoid multi-threading issues when different workbooks are accessed in
     // multiple threads at the same time
     private static final ThreadLocal<Short> lastDateFormat = new ThreadLocal<Short>() {
         @Override
@@ -264,7 +264,7 @@ public final class HSSFCellStyle impleme
     public void setQuotePrefixed(boolean quotePrefix) {
         _format.set123Prefix(quotePrefix);
     }
-    
+
     /**
      * Is "Quote Prefix" or "123 Prefix" enabled for the cell?
      */
@@ -272,7 +272,7 @@ public final class HSSFCellStyle impleme
     public boolean getQuotePrefixed() {
         return _format.get123Prefix();
     }
-    
+
     /**
      * set the type of horizontal alignment for the cell
      * @param align - the type of alignment
@@ -340,8 +340,8 @@ public final class HSSFCellStyle impleme
     /**
      * set the degree of rotation for the text in the cell
      *
-     * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF 
-     * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges 
+     * Note: HSSF uses values from -90 to 90 degrees, whereas XSSF
+     * uses values from 0 to 180 degrees. The implementations of this method will map between these two value-ranges
      * accordingly, however the corresponding getter is returning values in the range mandated by the current type
      * of Excel file-format that this CellStyle is applied to.
      *
@@ -352,7 +352,7 @@ public final class HSSFCellStyle impleme
     {
       if (rotation == 0xff) {
           // Special cases for vertically aligned text
-      } 
+      }
       else if ((rotation < 0)&&(rotation >= -90)) {
         //Take care of the funny 4th quadrant issue
         //The 4th quadrant (-1 to -90) is stored as (91 to 180)
@@ -407,7 +407,7 @@ public final class HSSFCellStyle impleme
     {
         return _format.getIndent();
     }
-    
+
     /**
      * set the type of border to use for the left border of the cell
      * @param border type
@@ -575,7 +575,7 @@ public final class HSSFCellStyle impleme
     {
         return _format.getBottomBorderPaletteIdx();
     }
-    
+
     /**
      * setting to one fills the cell with the foreground color... No idea about
      * other values
@@ -674,7 +674,7 @@ public final class HSSFCellStyle impleme
         }
         return result;
     }
-    
+
     @Override
     public HSSFColor getFillBackgroundColorColor() {
        HSSFPalette pallette = new HSSFPalette(
@@ -769,7 +769,7 @@ public final class HSSFCellStyle impleme
     public boolean getShrinkToFit() {
         return _format.getShrinkToFit();
     }
-    
+
     /**
      * Get the reading order, for RTL/LTR ordering of
      *  the text.
@@ -792,7 +792,7 @@ public final class HSSFCellStyle impleme
     public void setReadingOrder(short order) {
         _format.setReadingOrder(order);
     }
-    
+
     /**
      * Verifies that this style belongs to the supplied Workbook.
      * Will throw an exception if it belongs to a different one.
@@ -836,9 +836,9 @@ public final class HSSFCellStyle impleme
         if(_workbook != source._workbook) {
 
             lastDateFormat.set(Short.MIN_VALUE);
-            lastFormats.set(null);
-            getDataFormatStringCache.set(null);
-           
+            lastFormats.remove();
+            getDataFormatStringCache.remove();
+
             // Then we need to clone the format string,
             //  and update the format record for this
             short fmt = (short)_workbook.createFormat(source.getDataFormatString() );
@@ -894,5 +894,5 @@ public final class HSSFCellStyle impleme
         }
         return false;
     }
-    
+
 }

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java Sun Dec  8 23:29:50 2019
@@ -21,10 +21,7 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.security.GeneralSecurityException;
 
-import javax.crypto.BadPaddingException;
 import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.ShortBufferException;
 
 import org.apache.poi.EncryptedDocumentException;
 import org.apache.poi.util.IOUtils;
@@ -82,7 +79,7 @@ public abstract class ChunkedCipherInput
     @Override
     public int read() throws IOException {
         byte[] b = { 0 };
-        return (read(b) == 1) ? b[0] : -1;
+        return (read(b) == 1) ? (b[0] & 0xFF) : -1;
     }
 
     // do not implement! -> recursion
@@ -222,7 +219,7 @@ public abstract class ChunkedCipherInput
     /**
      * Used when BIFF header fields (sid, size) are being read. The internal
      * {@link Cipher} instance must step even when unencrypted bytes are read
-     * 
+     *
      */
     @Override
     public void readPlain(byte[] b, int off, int len) {
@@ -236,7 +233,7 @@ public abstract class ChunkedCipherInput
                 readBytes = read(b, off, len, true);
                 total += Math.max(0, readBytes);
             } while (readBytes > -1 && total < len);
-    
+
             if (total < len) {
                 throw new EOFException("buffer underrun");
             }

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/CryptoFunctions.java Sun Dec  8 23:29:50 2019
@@ -16,7 +16,7 @@
 ==================================================================== */
 package org.apache.poi.poifs.crypt;
 
-import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
 import java.security.DigestException;
 import java.security.GeneralSecurityException;
 import java.security.Key;
@@ -44,59 +44,62 @@ import org.apache.poi.util.StringUtil;
  * Helper functions used for standard and agile encryption
  */
 @Internal
-public class CryptoFunctions {
+public final class CryptoFunctions {
 
     //arbitrarily selected; may need to increase
     private static final int MAX_RECORD_LENGTH = 100_000;
 
+    private CryptoFunctions() {
+    }
+
     /**
      * <p><cite>2.3.4.7 ECMA-376 Document Encryption Key Generation (Standard Encryption)<br>
      * 2.3.4.11 Encryption Key Generation (Agile Encryption)</cite></p>
-     * 
+     *
      * <p>The encryption key for ECMA-376 document encryption [ECMA-376] using agile
      * encryption MUST be generated by using the following method, which is derived from PKCS #5:
      * <a href="https://www.ietf.org/rfc/rfc2898.txt">Password-Based Cryptography Version 2.0 [RFC2898]</a>.</p>
-     * 
+     *
      * <p>Let H() be a hashing algorithm as determined by the PasswordKeyEncryptor.hashAlgorithm
      * element, H_n be the hash data of the n-th iteration, and a plus sign (+) represent concatenation.
      * The password MUST be provided as an array of Unicode characters. Limitations on the length of the
      * password and the characters used by the password are implementation-dependent.
      * The initial password hash is generated as follows:</p>
-     * 
-     * 
+     *
+     *
      * <pre>H_0 = H(salt + password)</pre>
-     * 
+     *
      * <p>The salt used MUST be generated randomly. The salt MUST be stored in the
      * PasswordKeyEncryptor.saltValue element contained within the \EncryptionInfo stream as
      * specified in section 2.3.4.10. The hash is then iterated by using the following approach:</p>
-     * 
+     *
      * <pre>H_n = H(iterator + H_n-1)</pre>
-     * 
+     *
      * <p>where iterator is an unsigned 32-bit value that is initially set to 0x00000000 and then incremented
      * monotonically on each iteration until PasswordKey.spinCount iterations have been performed.
      * The value of iterator on the last iteration MUST be one less than PasswordKey.spinCount.</p>
-     * 
+     *
      * <p>For POI, H_final will be calculated by {@link #generateKey(byte[],HashAlgorithm,byte[],int)}</p>
      *
-     * @param password
-     * @param hashAlgorithm
-     * @param salt
-     * @param spinCount
+     * @param password the password
+     * @param hashAlgorithm the hash algorithm
+     * @param salt the initial salt value
+     * @param spinCount the repetition count
      * @return the hashed password
      */
     public static byte[] hashPassword(String password, HashAlgorithm hashAlgorithm, byte[] salt, int spinCount) {
         return hashPassword(password, hashAlgorithm, salt, spinCount, true);
     }
-        
+
     /**
      * Generalized method for read and write protection hash generation.
      * The difference is, read protection uses the order iterator then hash in the hash loop, whereas write protection
      * uses first the last hash value and then the current iterator value
      *
-     * @param password
-     * @param hashAlgorithm
-     * @param salt
-     * @param spinCount
+     * @param password the pasword
+     * @param hashAlgorithm the hash algorighm
+     * @param salt the initial salt value
+     * @param spinCount the repetition count
      * @param iteratorFirst if true, the iterator is hashed before the n-1 hash value,
      *        if false the n-1 hash value is applied first
      * @return the hashed password
@@ -107,16 +110,16 @@ public class CryptoFunctions {
         if (password == null) {
             password = Decryptor.DEFAULT_PASSWORD;
         }
-        
+
         MessageDigest hashAlg = getMessageDigest(hashAlgorithm);
-        
+
         hashAlg.update(salt);
         byte[] hash = hashAlg.digest(StringUtil.getToUnicodeLE(password));
         byte[] iterator = new byte[LittleEndianConsts.INT_SIZE];
 
         byte[] first = (iteratorFirst ? iterator : hash);
         byte[] second = (iteratorFirst ? hash : iterator);
-        
+
         try {
             for (int i = 0; i < spinCount; i++) {
                 LittleEndian.putInt(iterator, 0, i);
@@ -128,13 +131,13 @@ public class CryptoFunctions {
         } catch (DigestException e) {
             throw new EncryptedDocumentException("error in password hashing");
         }
-        
+
         return hash;
-    }    
+    }
 
     /**
      * <p><cite>2.3.4.12 Initialization Vector Generation (Agile Encryption)</cite></p>
-     * 
+     *
      * <p>Initialization vectors are used in all cases for agile encryption. An initialization vector MUST be
      * generated by using the following method, where H() is a hash function that MUST be the same as
      * specified in section 2.3.4.11 and a plus sign (+) represents concatenation:</p>
@@ -147,7 +150,7 @@ public class CryptoFunctions {
      *     corresponding to the cipherAlgorithm attribute, pad the array of bytes by appending 0x36 until
      *     the array is blockSize bytes. If the array of bytes is larger than blockSize bytes, truncate the
      *     array to blockSize bytes.</li>
-     * </ul> 
+     * </ul>
      **/
     public static byte[] generateIv(HashAlgorithm hashAlgorithm, byte[] salt, byte[] blockKey, int blockSize) {
         byte[] iv = salt;
@@ -161,23 +164,23 @@ public class CryptoFunctions {
 
     /**
      * <p><cite>2.3.4.11 Encryption Key Generation (Agile Encryption)</cite></p>
-     * 
+     *
      * <p>The final hash data that is used for an encryption key is then generated by using the following
      * method:</p>
-     * 
+     *
      * <pre>H_final = H(H_n + blockKey)</pre>
-     * 
+     *
      * <p>where blockKey represents an array of bytes used to prevent two different blocks from encrypting
      * to the same cipher text.</p>
-     * 
+     *
      * <p>If the size of the resulting H_final is smaller than that of PasswordKeyEncryptor.keyBits, the key
      * MUST be padded by appending bytes with a value of 0x36. If the hash value is larger in size than
-     * PasswordKeyEncryptor.keyBits, the key is obtained by truncating the hash value.</p> 
+     * PasswordKeyEncryptor.keyBits, the key is obtained by truncating the hash value.</p>
      *
-     * @param passwordHash
-     * @param hashAlgorithm
-     * @param blockKey
-     * @param keySize
+     * @param passwordHash the hashed password byte
+     * @param hashAlgorithm the hash algorithm
+     * @param blockKey the block key
+     * @param keySize the key size
      * @return intermediate key
      */
     public static byte[] generateKey(byte[] passwordHash, HashAlgorithm hashAlgorithm, byte[] blockKey, int keySize) {
@@ -198,9 +201,8 @@ public class CryptoFunctions {
      * @param vec the initialization vector (IV), can be null
      * @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
      * @return the requested cipher
-     * @throws GeneralSecurityException
      * @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified,
-     *   which depends on a missing bouncy castle provider 
+     *   which depends on a missing bouncy castle provider
      */
     public static Cipher getCipher(SecretKey key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode) {
         return getCipher(key, cipherAlgorithm, chain, vec, cipherMode, null);
@@ -218,14 +220,13 @@ public class CryptoFunctions {
      * @param cipherMode Cipher.DECRYPT_MODE or Cipher.ENCRYPT_MODE
      * @param padding the padding (null = NOPADDING, ANSIX923Padding, PKCS5Padding, PKCS7Padding, ISO10126Padding, ...)
      * @return the requested cipher
-     * @throws GeneralSecurityException
      * @throws EncryptedDocumentException if the initialization failed or if an algorithm was specified,
-     *   which depends on a missing bouncy castle provider 
+     *   which depends on a missing bouncy castle provider
      */
     public static Cipher getCipher(Key key, CipherAlgorithm cipherAlgorithm, ChainingMode chain, byte[] vec, int cipherMode, String padding) {
         int keySizeInBytes = key.getEncoded().length;
         if (padding == null) padding = "NoPadding";
-        
+
         try {
             // Ensure the JCE policies files allow for this sized key
             if (Cipher.getMaxAllowedKeyLength(cipherAlgorithm.jceId) < keySizeInBytes*8) {
@@ -241,7 +242,7 @@ public class CryptoFunctions {
             } else {
                 cipher = Cipher.getInstance(cipherAlgorithm.jceId + "/" + chain.jceId + "/" + padding);
             }
-            
+
             if (vec == null) {
                 cipher.init(cipherMode, key);
             } else {
@@ -257,10 +258,10 @@ public class CryptoFunctions {
         } catch (GeneralSecurityException e) {
             throw new EncryptedDocumentException(e);
         }
-    }    
-    
+    }
+
     /**
-     * Returns a new byte array with a truncated to the given size. 
+     * Returns a new byte array with a truncated to the given size.
      * If the hash has less then size bytes, it will be filled with 0x36-bytes
      *
      * @param hash the to be truncated/filled hash byte array
@@ -272,7 +273,7 @@ public class CryptoFunctions {
     }
 
     /**
-     * Returns a new byte array with a truncated to the given size. 
+     * Returns a new byte array with a truncated to the given size.
      * If the hash has less then size bytes, it will be filled with 0-bytes
      *
      * @param hash the to be truncated/filled hash byte array
@@ -282,16 +283,16 @@ public class CryptoFunctions {
     public static byte[] getBlock0(byte[] hash, int size) {
         return getBlockX(hash, size, (byte)0);
     }
-    
+
     private static byte[] getBlockX(byte[] hash, int size, byte fill) {
         if (hash.length == size) return hash;
-        
+
         byte[] result = IOUtils.safelyAllocate(size, MAX_RECORD_LENGTH);
         Arrays.fill(result, fill);
         System.arraycopy(hash, 0, result, 0, Math.min(result.length, hash.length));
         return result;
     }
-    
+
     public static MessageDigest getMessageDigest(HashAlgorithm hashAlgorithm) {
         try {
             if (hashAlgorithm.needsBouncyCastle) {
@@ -304,7 +305,7 @@ public class CryptoFunctions {
             throw new EncryptedDocumentException("hash algo not supported", e);
         }
     }
-    
+
     public static Mac getMac(HashAlgorithm hashAlgorithm) {
         try {
             if (hashAlgorithm.needsBouncyCastle) {
@@ -323,7 +324,7 @@ public class CryptoFunctions {
         if (Security.getProvider("BC") != null) {
             return;
         }
-        
+
         try {
             ClassLoader cl = CryptoFunctions.class.getClassLoader();
             String bcProviderName = "org.bouncycastle.jce.provider.BouncyCastleProvider";
@@ -370,7 +371,7 @@ public class CryptoFunctions {
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd926947.aspx">2.3.7.1 Binary Document Password Verifier Derivation Method 1</a>
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd905229.aspx">2.3.7.4 Binary Document Password Verifier Derivation Method 2</a>
      * @see <a href="http://www.ecma-international.org/news/TC45_current_work/Office Open XML Part 4 - Markup Language Reference.pdf">Part 4 - Markup Language Reference - Ecma International - 3.2.12 fileSharing</a>
-     * 
+     *
      * @param password the password
      * @return the verifier (actually a short value)
      */
@@ -380,7 +381,7 @@ public class CryptoFunctions {
         }
 
         byte[] arrByteChars = toAnsiPassword(password);
-        
+
         // SET Verifier TO 0x0000
         short verifier = 0;
 
@@ -391,27 +392,27 @@ public class CryptoFunctions {
                 verifier = rotateLeftBase15Bit(verifier);
                 verifier ^= arrByteChars[i];
             }
-    
+
             // as we haven't prepended the password length into the input array
             // we need to do it now separately ...
             verifier = rotateLeftBase15Bit(verifier);
             verifier ^= arrByteChars.length;
-            
+
             // RETURN Verifier BITWISE XOR 0xCE4B
             verifier ^= 0xCE4B; // (0x8000 | ('N' << 8) | 'K')
         }
-        
+
         return verifier & 0xFFFF;
     }
- 
+
     /**
      * This method generates the xor verifier for word documents &lt; 2007 (method 2).
      * Its output will be used as password input for the newer word generations which
      * utilize a real hashing algorithm like sha1.
-     * 
+     *
      * @param password the password
      * @return the hashed password
-     * 
+     *
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd905229.aspx">2.3.7.4 Binary Document Password Verifier Derivation Method 2</a>
      * @see <a href="http://blogs.msdn.com/b/vsod/archive/2010/04/05/how-to-set-the-editing-restrictions-in-word-using-open-xml-sdk-2-0.aspx">How to set the editing restrictions in Word using Open XML SDK 2.0</a>
      * @see <a href="http://www.aspose.com/blogs/aspose-blogs/vladimir-averkin/archive/2007/08/20/funny-how-the-new-powerful-cryptography-implemented-in-word-2007-turns-it-into-a-perfect-tool-for-document-password-removal.html">Funny: How the new powerful cryptography implemented in Word 2007 turns it into a perfect tool for document password removal.</a>
@@ -425,42 +426,43 @@ public class CryptoFunctions {
         byte[] generatedKey = new byte[4];
 
         //Maximum length of the password is 15 chars.
-        final int maxPasswordLength = 15; 
-        
+        final int maxPasswordLength = 15;
+
         if (!password.isEmpty()) {
             // Truncate the password to 15 characters
             password = password.substring(0, Math.min(password.length(), maxPasswordLength));
 
             byte[] arrByteChars = toAnsiPassword(password);
-            
+
             // Compute the high-order word of the new key:
 
-            // --> Initialize from the initial code array (see below), depending on the passwords length. 
+            // --> Initialize from the initial code array (see below), depending on the passwords length.
             int highOrderWord = INITIAL_CODE_ARRAY[arrByteChars.length - 1];
 
             // --> For each character in the password:
-            //      --> For every bit in the character, starting with the least significant and progressing to (but excluding) 
-            //          the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from 
+            //      --> For every bit in the character, starting with the least significant and progressing to (but excluding)
+            //          the most significant, if the bit is set, XOR the keys high-order word with the corresponding word from
             //          the Encryption Matrix
-            for (int i = 0; i < arrByteChars.length; i++) {
-                int tmp = maxPasswordLength - arrByteChars.length + i;
-                for (int intBit = 0; intBit < 7; intBit++) {
-                    if ((arrByteChars[i] & (0x0001 << intBit)) != 0) {
-                        highOrderWord ^= ENCRYPTION_MATRIX[tmp][intBit];
+            int line = maxPasswordLength - arrByteChars.length;
+            for (byte ch : arrByteChars) {
+                for (int xor : ENCRYPTION_MATRIX[line++]) {
+                    if ((ch & 1) == 1) {
+                        highOrderWord ^= xor;
                     }
+                    ch >>>= 1;
                 }
             }
-            
+
             // Compute the low-order word of the new key:
             int verifier = createXorVerifier1(password);
 
             // The byte order of the result shall be reversed [password "Example": 0x64CEED7E becomes 7EEDCE64],
             // and that value shall be hashed as defined by the attribute values.
-            
+
             LittleEndian.putShort(generatedKey, 0, (short)verifier);
             LittleEndian.putShort(generatedKey, 2, (short)highOrderWord);
         }
-        
+
         return LittleEndian.getInt(generatedKey);
     }
 
@@ -471,16 +473,16 @@ public class CryptoFunctions {
         int hashedPassword = createXorVerifier2(password);
         return String.format(Locale.ROOT, "%1$08X", hashedPassword);
     }
-    
+
     /**
-     * Convenience function which returns the reversed xored-hashed password for further 
+     * Convenience function which returns the reversed xored-hashed password for further
      * processing in word documents 2007 and newer, which utilize a real hashing algorithm like sha1.
      */
     public static String xorHashPasswordReversed(String password) {
         int hashedPassword = createXorVerifier2(password);
-        
+
         return String.format(Locale.ROOT, "%1$02X%2$02X%3$02X%4$02X"
-            , ( hashedPassword >>> 0 ) & 0xFF
+            , (hashedPassword) & 0xFF
             , ( hashedPassword >>> 8 ) & 0xFF
             , ( hashedPassword >>> 16 ) & 0xFF
             , ( hashedPassword >>> 24 ) & 0xFF
@@ -492,7 +494,7 @@ public class CryptoFunctions {
      *
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd924704.aspx">2.3.7.2 Binary Document XOR Array Initialization Method 1</a>
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd905229.aspx">2.3.7.4 Binary Document Password Verifier Derivation Method 2</a>
-     * 
+     *
      * @param password the password
      * @return the xor key
      */
@@ -503,7 +505,7 @@ public class CryptoFunctions {
     }
 
     /**
-     * Creates an byte array for xor obfuscation (method 1) 
+     * Creates an byte array for xor obfuscation (method 1)
      *
      * @see <a href="http://msdn.microsoft.com/en-us/library/dd924704.aspx">2.3.7.2 Binary Document XOR Array Initialization Method 1</a>
      * @see <a href="http://docs.libreoffice.org/oox/html/binarycodec_8cxx_source.html">Libre Office implementation</a>
@@ -515,17 +517,17 @@ public class CryptoFunctions {
         if (password.length() > 15) {
             password = password.substring(0, 15);
         }
-        byte[] passBytes = password.getBytes(Charset.forName("ASCII"));
-        
+        byte[] passBytes = password.getBytes(StandardCharsets.US_ASCII);
+
         // this code is based on the libre office implementation.
-        // The MS-OFFCRYPTO misses some infos about the various rotation sizes 
+        // The MS-OFFCRYPTO misses some infos about the various rotation sizes
         byte[] obfuscationArray = new byte[16];
         System.arraycopy(passBytes, 0, obfuscationArray, 0, passBytes.length);
         System.arraycopy(PAD_ARRAY, 0, obfuscationArray, passBytes.length, PAD_ARRAY.length-passBytes.length+1);
-        
+
         int xorKey = createXorKey1(password);
-        
-        // rotation of key values is application dependent - Excel = 2 / Word = 7 
+
+        // rotation of key values is application dependent - Excel = 2 / Word = 7
         int nRotateSize = 2;
 
         byte[] baseKeyLE = {(byte) (xorKey & 0xFF), (byte) ((xorKey >>> 8) & 0xFF)};
@@ -533,26 +535,26 @@ public class CryptoFunctions {
             obfuscationArray[i] ^= baseKeyLE[i&1];
             obfuscationArray[i] = rotateLeft(obfuscationArray[i], nRotateSize);
         }
-        
+
         return obfuscationArray;
     }
-    
+
     /**
      * The provided Unicode password string is converted to a ANSI string
      *
      * @param password the password
      * @return the ansi bytes
-     * 
+     *
      * @see <a href="http://www.ecma-international.org/news/TC45_current_work/Office%20Open%20XML%20Part%204%20-%20Markup%20Language%20Reference.pdf">Part 4 - Markup Language Reference - Ecma International - section 3.2.29 (workbookProtection)</a>
      */
     private static byte[] toAnsiPassword(String password) {
-        // TODO: charset conversion (see ecma spec) 
-        
+        // TODO: charset conversion (see ecma spec)
+
         // Get the single-byte values by iterating through the Unicode characters.
         // For each character, if the low byte is not equal to 0, take it.
         // Otherwise, take the high byte.
         byte[] arrByteChars = new byte[password.length()];
-        
+
         for (int i = 0; i < password.length(); i++) {
             int intTemp = password.charAt(i);
             byte lowByte = (byte)(intTemp & 0xFF);
@@ -562,11 +564,11 @@ public class CryptoFunctions {
 
         return arrByteChars;
     }
-    
+
     private static byte rotateLeft(byte bits, int shift) {
         return (byte)(((bits & 0xff) << shift) | ((bits & 0xff) >>> (8 - shift)));
     }
-    
+
     private static short rotateLeftBase15Bit(short verifier) {
         /*
          * IF (Verifier BITWISE AND 0x4000) is 0x0000

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentInputStream.java Sun Dec  8 23:29:50 2019
@@ -27,19 +27,19 @@ import org.apache.poi.util.Internal;
 
 /**
  * A seekable InputStream, which is used to decrypt/extract the document entries
- * within the encrypted stream 
+ * within the encrypted stream
  */
 @Internal
 /* package */ class CryptoAPIDocumentInputStream extends ByteArrayInputStream {
     private Cipher cipher;
     private final CryptoAPIDecryptor decryptor;
     private byte[] oneByte = {0};
-    
+
     public void seek(int newpos) {
         if (newpos > count) {
             throw new ArrayIndexOutOfBoundsException(newpos);
         }
-        
+
         this.pos = newpos;
         mark = newpos;
     }
@@ -60,7 +60,7 @@ import org.apache.poi.util.Internal;
         } catch (ShortBufferException e) {
             throw new EncryptedDocumentException(e);
         }
-        return oneByte[0];
+        return oneByte[0] & 0xFF;
     }
 
     @Override

Modified: poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/crypt/cryptoapi/CryptoAPIDocumentOutputStream.java Sun Dec  8 23:29:50 2019
@@ -37,21 +37,21 @@ import org.apache.poi.util.Internal;
         this.encryptor = encryptor;
         cipher = encryptor.initCipherForBlock(null, 0);
     }
-    
+
     public byte[] getBuf() {
         return buf;
     }
-    
+
     public void setSize(int count) {
         this.count = count;
     }
-    
+
     public void setBlock(int block) throws GeneralSecurityException {
         encryptor.initCipherForBlock(cipher, block);
     }
-    
+
     @Override
-    public void write(int b) {
+    public synchronized void write(int b) {
         try {
             oneByte[0] = (byte)b;
             cipher.update(oneByte, 0, 1, oneByte, 0);
@@ -62,7 +62,7 @@ import org.apache.poi.util.Internal;
     }
 
     @Override
-    public void write(byte[] b, int off, int len) {
+    public synchronized void write(byte[] b, int off, int len) {
         try {
             cipher.update(b, off, len, b, off);
             super.write(b, off, len);

Modified: poi/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java (original)
+++ poi/trunk/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java Sun Dec  8 23:29:50 2019
@@ -68,9 +68,9 @@ public final class DocumentInputStream e
 
     /**
      * Create an InputStream from the specified DocumentEntry
-     * 
+     *
      * @param document the DocumentEntry to be read
-     * 
+     *
      * @exception IOException if the DocumentEntry cannot be opened (like, maybe it has
      *                been deleted?)
      */
@@ -91,7 +91,7 @@ public final class DocumentInputStream e
         DocumentNode doc = (DocumentNode)document;
         DocumentProperty property = (DocumentProperty)doc.getProperty();
         _document = new POIFSDocument(
-                property, 
+                property,
                 ((DirectoryNode)doc.getParent()).getFileSystem()
         );
         _data = _document.getBlockIterator();
@@ -99,7 +99,7 @@ public final class DocumentInputStream e
 
     /**
      * Create an InputStream from the specified Document
-     * 
+     *
      * @param document the Document to be read
      */
     public DocumentInputStream(POIFSDocument document) {
@@ -146,7 +146,7 @@ public final class DocumentInputStream e
     }
 
     @Override
-    public void mark(int ignoredReadlimit) {
+    public synchronized void mark(int ignoredReadlimit) {
         _marked_offset = _current_offset;
         _marked_offset_count = Math.max(0, _current_block_count - 1);
     }
@@ -159,13 +159,7 @@ public final class DocumentInputStream e
         }
         byte[] b = new byte[1];
         int result = read(b, 0, 1);
-        if(result >= 0) {
-            if(b[0] < 0) {
-                return b[0]+256;
-            }
-            return b[0];
-        }
-        return result;
+        return (result == EOF) ? EOF : (b[0] & 0xFF);
     }
 
     @Override
@@ -199,7 +193,7 @@ public final class DocumentInputStream e
      * method repositions the stream to its beginning.
      */
     @Override
-    public void reset() {
+    public synchronized void reset() {
         // Special case for reset to the start
         if(_marked_offset == 0 && _marked_offset_count == 0) {
             _current_block_count = _marked_offset_count;
@@ -216,15 +210,15 @@ public final class DocumentInputStream e
 		   _buffer = _data.next();
 		   _current_offset += _buffer.remaining();
 		}
-		
+
       _current_block_count = _marked_offset_count;
-      
+
       // Do we need to position within it?
       if(_current_offset != _marked_offset) {
    		// Grab the right block
          _buffer = _data.next();
          _current_block_count++;
-         
+
    		// Skip to the right place in it
          // (It should be positioned already at the start of the block,
          //  we need to move further inside the block)
@@ -250,9 +244,9 @@ public final class DocumentInputStream e
 		} else if (new_offset > _document_size) {
 			new_offset = _document_size;
 		}
-		
+
 		long rval = new_offset - _current_offset;
-		
+
 		// TODO Do this better
 		byte[] skip = IOUtils.safelyAllocate(rval, Integer.MAX_VALUE);
 		readFully(skip);
@@ -298,7 +292,7 @@ public final class DocumentInputStream e
 		      _current_block_count++;
 		      _buffer = _data.next();
 		   }
-		   
+
 		   int limit = Math.min(len-read, _buffer.remaining());
 		   _buffer.get(buf, off+read, limit);
          _current_offset += limit;

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawFactory.java Sun Dec  8 23:29:50 2019
@@ -47,17 +47,21 @@ public class DrawFactory {
      * This is a fallback, for operations where usercode can't set a graphics context.
      * Preferably use the rendering hint {@link Drawable#DRAW_FACTORY} to set the factory.
      *
-     * @param factory the custom factory
+     * @param factory the custom factory or {@code null} to reset/remove the default factory
      */
     @SuppressWarnings("unused")
     public static void setDefaultFactory(DrawFactory factory) {
-        defaultFactory.set(factory);
+        if (factory == null) {
+            defaultFactory.remove();
+        } else {
+            defaultFactory.set(factory);
+        }
     }
 
     /**
      * Returns the DrawFactory, preferably via a graphics instance.
      * If graphics is null, the current thread local is checked or
-     * if it is not set, a new factory is created. 
+     * if it is not set, a new factory is created.
      *
      * @param graphics the current graphics context or null
      * @return the draw factory
@@ -112,7 +116,7 @@ public class DrawFactory {
         } else if (shape.getClass().isAnnotationPresent(DrawNotImplemented.class)) {
             return new DrawNothing(shape);
         }
-        
+
         throw new IllegalArgumentException("Unsupported shape type: "+shape.getClass());
     }
 
@@ -139,11 +143,11 @@ public class DrawFactory {
     public DrawConnectorShape getDrawable(ConnectorShape<?,?> shape) {
         return new DrawConnectorShape(shape);
     }
-    
+
     public DrawTableShape getDrawable(TableShape<?,?> shape) {
         return new DrawTableShape(shape);
     }
-    
+
     public DrawTextShape getDrawable(TextShape<?,?> shape) {
         return new DrawTextShape(shape);
     }
@@ -151,15 +155,15 @@ public class DrawFactory {
     public DrawGroupShape getDrawable(GroupShape<?,?> shape) {
         return new DrawGroupShape(shape);
     }
-    
+
     public DrawPictureShape getDrawable(PictureShape<?,?> shape) {
         return new DrawPictureShape(shape);
     }
-    
+
     public DrawGraphicalFrame getDrawable(GraphicalFrame<?,?> shape) {
         return new DrawGraphicalFrame(shape);
     }
-    
+
     public DrawTextParagraph getDrawable(TextParagraph<?,?,?> paragraph) {
         return new DrawTextParagraph(paragraph);
     }
@@ -167,12 +171,12 @@ public class DrawFactory {
     public DrawBackground getDrawable(Background<?,?> shape) {
         return new DrawBackground(shape);
     }
-    
+
     @SuppressWarnings("WeakerAccess")
     public DrawTextFragment getTextFragment(TextLayout layout, AttributedString str) {
         return new DrawTextFragment(layout, str);
     }
-    
+
     public DrawPaint getPaint(PlaceableShape<?,?> shape) {
         return new DrawPaint(shape);
     }
@@ -183,7 +187,7 @@ public class DrawFactory {
      *
      * @param graphics the graphics context to draw to
      * @param shape the shape
-     * @param bounds the bounds within the graphics context to draw to 
+     * @param bounds the bounds within the graphics context to draw to
      */
     public void drawShape(Graphics2D graphics, Shape<?,?> shape, Rectangle2D bounds) {
         Rectangle2D shapeBounds = shape.getAnchor();
@@ -202,7 +206,7 @@ public class DrawFactory {
                 tx.translate(-shapeBounds.getCenterX(), -shapeBounds.getCenterY());
             }
             graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, tx);
-            
+
             Drawable d = getDrawable(shape);
             d.applyTransform(graphics);
             d.draw(graphics);
@@ -210,7 +214,7 @@ public class DrawFactory {
             graphics.setRenderingHint(Drawable.GROUP_TRANSFORM, txg);
         }
     }
-    
+
 
     /**
      * Return a FontManager, either registered beforehand or a default implementation

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawShape.java Sun Dec  8 23:29:50 2019
@@ -60,56 +60,52 @@ public class DrawShape implements Drawab
             return;
         }
 
-        final PlaceableShape<?,?> ps = (PlaceableShape<?,?>)shape;
-        final boolean isHSLF = isHSLF(shape);
+        final Rectangle2D anchor = getAnchor(graphics, (PlaceableShape<?,?>)shape);
+        if (anchor == null) {
+            return;
+        }
 
-        final Rectangle2D anchor = getAnchor(graphics, ps);
+        if (isHSLF(shape)) {
+            flipHorizontal(graphics, anchor);
+            flipVertical(graphics, anchor);
+            rotate(graphics, anchor);
+        } else {
+            rotate(graphics, anchor);
+            flipHorizontal(graphics, anchor);
+            flipVertical(graphics, anchor);
+        }
+    }
 
-        char[] cmds = isHSLF ? new char[]{'h', 'v', 'r'} : new char[]{'r', 'h', 'v'};
-        for (char ch : cmds) {
-            switch (ch) {
-            case 'h':
-                //flip horizontal
-                if (ps.getFlipHorizontal()) {
-                    graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
-                    graphics.scale(-1, 1);
-                    graphics.translate(-anchor.getX(), -anchor.getY());
-                }
-                break;
-            case 'v':
-                //flip vertical
-                if (ps.getFlipVertical()) {
-                    graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
-                    graphics.scale(1, -1);
-                    graphics.translate(-anchor.getX(), -anchor.getY());
-                }
-                break;
-            case 'r':
-                // rotation
-                double rotation = ps.getRotation();
-                if (rotation != 0.) {
-                    // PowerPoint rotates shapes relative to the geometric center
-                    double centerX = anchor.getCenterX();
-                    double centerY = anchor.getCenterY();
+    private void flipHorizontal(Graphics2D graphics, Rectangle2D anchor) {
+        assert(shape instanceof PlaceableShape && anchor != null);
+        if (((PlaceableShape<?,?>)shape).getFlipHorizontal()) {
+            graphics.translate(anchor.getX() + anchor.getWidth(), anchor.getY());
+            graphics.scale(-1, 1);
+            graphics.translate(-anchor.getX(), -anchor.getY());
+        }
+    }
 
+    private void flipVertical(Graphics2D graphics, Rectangle2D anchor) {
+        assert(shape instanceof PlaceableShape && anchor != null);
+        if (((PlaceableShape<?,?>)shape).getFlipVertical()) {
+            graphics.translate(anchor.getX(), anchor.getY() + anchor.getHeight());
+            graphics.scale(1, -1);
+            graphics.translate(-anchor.getX(), -anchor.getY());
+        }
+    }
 
-                    // transformation is applied reversed ...
-                    graphics.translate(centerX, centerY);
-                    graphics.rotate(Math.toRadians(rotation));
-                    graphics.translate(-centerX, -centerY);
-                }
-                break;
-            default:
-                throw new RuntimeException("unexpected transform code " + ch);
-            }
+    private void rotate(Graphics2D graphics, Rectangle2D anchor) {
+        assert(shape instanceof PlaceableShape && anchor != null);
+        double rotation = ((PlaceableShape<?,?>)shape).getRotation();
+        if (rotation != 0.) {
+            // PowerPoint rotates shapes relative to the geometric center
+            graphics.rotate(Math.toRadians(rotation), anchor.getCenterX(), anchor.getCenterY());
         }
+
     }
 
     private static double safeScale(double dim1, double dim2) {
-        if (dim1 == 0.) {
-            return 1;
-        }
-        return (dim2 == 0.) ? 1 : dim1/dim2;
+        return (dim1 == 0. || dim2 == 0.) ? 1 : dim1/dim2;
     }
 
     @Override
@@ -160,15 +156,11 @@ public class DrawShape implements Drawab
                 // this handling is only based on try and error ... not sure why h/xslf is handled differently.
 
                 if (!isHSLF) {
-                    txs2.translate(centerX, centerY);
-                    txs2.quadrantRotate(1);
-                    txs2.translate(-centerX, -centerY);
+                    txs2.quadrantRotate(1, centerX, centerY);
                     txs2.concatenate(tx);
                 }
 
-                txs2.translate(centerX, centerY);
-                txs2.quadrantRotate(3);
-                txs2.translate(-centerX, -centerY);
+                txs2.quadrantRotate(3, centerX, centerY);
 
                 if (isHSLF) {
                     txs2.concatenate(tx);

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/Delta.java Sun Dec  8 23:29:50 2019
@@ -18,9 +18,11 @@
 package org.apache.poi.ss.formula.functions;
 
 import org.apache.poi.ss.formula.OperationEvaluationContext;
-import org.apache.poi.ss.formula.eval.*;
-
-import java.math.BigDecimal;
+import org.apache.poi.ss.formula.eval.ErrorEval;
+import org.apache.poi.ss.formula.eval.EvaluationException;
+import org.apache.poi.ss.formula.eval.NumberEval;
+import org.apache.poi.ss.formula.eval.OperandResolver;
+import org.apache.poi.ss.formula.eval.ValueEval;
 
 /**
  * Implementation for Excel DELTA() function.<p>
@@ -46,33 +48,20 @@ public final class Delta extends Fixed2A
     private final static NumberEval ZERO = new NumberEval(0);
 
     public ValueEval evaluate(int srcRowIndex, int srcColumnIndex, ValueEval arg1, ValueEval arg2) {
-        ValueEval veText1;
         try {
-            veText1 = OperandResolver.getSingleValue(arg1, srcRowIndex, srcColumnIndex);
-        } catch (EvaluationException e) {
-            return e.getErrorEval();
-        }
-        String strText1 = OperandResolver.coerceValueToString(veText1);
-        Double number1 = OperandResolver.parseDouble(strText1);
-        if (number1 == null) {
-            return ErrorEval.VALUE_INVALID;
-        }
+            Double number1 = evaluateValue(arg1, srcRowIndex, srcColumnIndex);
+            if (number1 == null) {
+                return ErrorEval.VALUE_INVALID;
+            }
+            Double number2 = evaluateValue(arg2, srcRowIndex, srcColumnIndex);
+            if (number2 == null) {
+                return ErrorEval.VALUE_INVALID;
+            }
 
-        ValueEval veText2;
-        try {
-            veText2 = OperandResolver.getSingleValue(arg2, srcRowIndex, srcColumnIndex);
+            return (number1.compareTo(number2) == 0) ? ONE : ZERO;
         } catch (EvaluationException e) {
             return e.getErrorEval();
         }
-
-        String strText2 = OperandResolver.coerceValueToString(veText2);
-        Double number2 = OperandResolver.parseDouble(strText2);
-        if (number2 == null) {
-            return ErrorEval.VALUE_INVALID;
-        }
-
-        int result = new BigDecimal(number1.doubleValue()).compareTo(new BigDecimal(number2.doubleValue()));
-        return result == 0 ? ONE : ZERO;
     }
 
     public ValueEval evaluate(ValueEval[] args, OperationEvaluationContext ec) {
@@ -82,4 +71,10 @@ public final class Delta extends Fixed2A
 
         return ErrorEval.VALUE_INVALID;
     }
+
+    private static Double evaluateValue(ValueEval arg, int srcRowIndex, int srcColumnIndex) throws EvaluationException {
+        ValueEval veText = OperandResolver.getSingleValue(arg, srcRowIndex, srcColumnIndex);
+        String strText1 = OperandResolver.coerceValueToString(veText);
+        return OperandResolver.parseDouble(strText1);
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/Fixed.java Sun Dec  8 23:29:50 2019
@@ -64,7 +64,8 @@ public final class Fixed implements Func
         }
         return ErrorEval.VALUE_INVALID;
     }
-    
+
+    @SuppressWarnings("squid:S2111")
     private ValueEval fixed(
             ValueEval numberParam, ValueEval placesParam,
             ValueEval skipThousandsSeparatorParam,
@@ -85,16 +86,16 @@ public final class Fixed implements Func
             Boolean skipThousandsSeparator =
                     OperandResolver.coerceValueToBoolean(
                     skipThousandsSeparatorValueEval, false);
-            
+
             // Round number to respective places.
             number = number.setScale(places, RoundingMode.HALF_UP);
-            
+
             // Format number conditionally using a thousands separator.
             NumberFormat nf = NumberFormat.getNumberInstance(Locale.US);
             DecimalFormat formatter = (DecimalFormat)nf;
             formatter.setGroupingUsed(!(skipThousandsSeparator != null && skipThousandsSeparator));
-            formatter.setMinimumFractionDigits(places >= 0 ? places : 0);
-            formatter.setMaximumFractionDigits(places >= 0 ? places : 0);
+            formatter.setMinimumFractionDigits(Math.max(places, 0));
+            formatter.setMaximumFractionDigits(Math.max(places, 0));
             String numberString = formatter.format(number.doubleValue());
 
             // Return the result as a StringEval.

Modified: poi/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/formula/functions/Irr.java Sun Dec  8 23:29:50 2019
@@ -31,6 +31,8 @@ import org.apache.poi.ss.formula.eval.Va
  * @see <a href="http://office.microsoft.com/en-us/excel-help/irr-HP005209146.aspx">Excel IRR</a>
  */
 public final class Irr implements Function {
+    private static final int MAX_ITERATION_COUNT = 20;
+    private static final double ABSOLUTE_ACCURACY = 1E-7;
 
 
     public ValueEval evaluate(final ValueEval[] args, final int srcRowIndex, final int srcColumnIndex) {
@@ -89,27 +91,24 @@ public final class Irr implements Functi
      *     http://en.wikipedia.org/wiki/Newton%27s_method</a>
      */
     public static double irr(double[] values, double guess) {
-        final int maxIterationCount = 20;
-        final double absoluteAccuracy = 1E-7;
 
         double x0 = guess;
-        double x1;
 
-        int i = 0;
-        while (i < maxIterationCount) {
+        for (int i = 0; i < MAX_ITERATION_COUNT; i++) {
 
             // the value of the function (NPV) and its derivate can be calculated in the same loop
             final double factor = 1.0 + x0;
-            int k = 0;
-            double fValue = values[k];
+            double denominator = factor;
+            if (denominator == 0) {
+                return Double.NaN;
+            }
+
+            double fValue = values[0];
             double fDerivative = 0;
-            for (double denominator = factor; ++k < values.length; ) {
+            for (int k = 1; k < values.length; k++) {
                 final double value = values[k];
                 fValue += value / denominator;
                 denominator *= factor;
-                if (denominator == 0) {
-                    return Double.NaN;
-                }
                 fDerivative -= k * value / denominator;
             }
 
@@ -117,14 +116,13 @@ public final class Irr implements Functi
             if (fDerivative == 0) {
                 return Double.NaN;
             }
-            x1 =  x0 - fValue/fDerivative;
+            double x1 =  x0 - fValue/fDerivative;
 
-            if (Math.abs(x1 - x0) <= absoluteAccuracy) {
+            if (Math.abs(x1 - x0) <= ABSOLUTE_ACCURACY) {
                 return x1;
             }
 
             x0 = x1;
-            ++i;
         }
         // maximum number of iterations is exceeded
         return Double.NaN;

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/DataFormatter.java Sun Dec  8 23:29:50 2019
@@ -16,7 +16,7 @@
 
    2012 - Alfresco Software, Ltd.
    Alfresco Software has modified source of this file
-   The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src 
+   The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src
 ==================================================================== */
 package org.apache.poi.ss.usermodel;
 
@@ -111,12 +111,12 @@ import org.apache.poi.util.POILogger;
  * <p>
  *  Some formats are automatically "localized" by Excel, eg show as mm/dd/yyyy when
  *   loaded in Excel in some Locales but as dd/mm/yyyy in others. These are always
- *   returned in the "default" (US) format, as stored in the file. 
- *  Some format strings request an alternate locale, eg 
+ *   returned in the "default" (US) format, as stored in the file.
+ *  Some format strings request an alternate locale, eg
  *   <code>[$-809]d/m/yy h:mm AM/PM</code> which explicitly requests UK locale.
  *   These locale directives are (currently) ignored.
  *  You can use {@link DateFormatConverter} to do some of this localisation if
- *   you need it. 
+ *   you need it.
  */
 public class DataFormatter implements Observer {
     private static final String defaultFractionWholePartFormat = "#";
@@ -129,13 +129,13 @@ public class DataFormatter implements Ob
 
     /** Pattern to find "AM/PM" marker */
     private static final Pattern amPmPattern = Pattern.compile("(([AP])[M/P]*)", Pattern.CASE_INSENSITIVE);
-    
+
     /** Pattern to find formats with condition ranges e.g. [>=100] */
     private static final Pattern rangeConditionalPattern = Pattern.compile(".*\\[\\s*(>|>=|<|<=|=)\\s*[0-9]*\\.*[0-9].*");
 
-    /** 
+    /**
      * A regex to find locale patterns like [$$-1009] and [$?-452].
-     * Note that we don't currently process these into locales 
+     * Note that we don't currently process these into locales
      */
     private static final Pattern localePatternGroup = Pattern.compile("(\\[\\$[^-\\]]*-[0-9A-Z]+])");
 
@@ -144,14 +144,14 @@ public class DataFormatter implements Ob
      * Allowed colours are: Black, Blue, Cyan, Green,
      *  Magenta, Red, White, Yellow, "Color n" (1<=n<=56)
      */
-    private static final Pattern colorPattern = 
+    private static final Pattern colorPattern =
        Pattern.compile("(\\[BLACK])|(\\[BLUE])|(\\[CYAN])|(\\[GREEN])|" +
        		"(\\[MAGENTA])|(\\[RED])|(\\[WHITE])|(\\[YELLOW])|" +
        		"(\\[COLOR\\s*\\d])|(\\[COLOR\\s*[0-5]\\d])", Pattern.CASE_INSENSITIVE);
 
     /**
      * A regex to identify a fraction pattern.
-     * This requires that replaceAll("\\?", "#") has already been called 
+     * This requires that replaceAll("\\?", "#") has already been called
      */
     private static final Pattern fractionPattern = Pattern.compile("(?:([#\\d]+)\\s+)?(#+)\\s*/\\s*([#\\d]+)");
 
@@ -162,10 +162,10 @@ public class DataFormatter implements Ob
 
     /**
      * A regex to detect if an alternate grouping character is used
-     *  in a numeric format 
+     *  in a numeric format
      */
     private static final Pattern alternateGrouping = Pattern.compile("([#0]([^.#0])[#0]{3})");
-    
+
     /**
       * Cells formatted with a date or time format and which contain invalid date or time values
      *  show 255 pound signs ("#").
@@ -191,7 +191,7 @@ public class DataFormatter implements Ob
      * A default date format, if no date format was given
      */
     private DateFormat defaultDateformat;
-    
+
     /** <em>General</em> format for numbers. */
     private Format generalNumberFormat;
 
@@ -208,10 +208,10 @@ public class DataFormatter implements Ob
 
     /** stores the locale valid it the last formatting call */
     private Locale locale;
-    
+
     /** stores if the locale should change according to {@link LocaleUtil#getUserLocale()} */
     private boolean localeIsAdapting;
-    
+
     private class LocaleChangeObservable extends Observable {
         void checkForLocaleChange() {
             checkForLocaleChange(LocaleUtil.getUserLocale());
@@ -223,13 +223,13 @@ public class DataFormatter implements Ob
             notifyObservers(newLocale);
         }
     }
-    
+
     /** the Observable to notify, when the locale has been changed */
     private final LocaleChangeObservable localeChangedObservable = new LocaleChangeObservable();
-    
+
     /** For logging any problems we find */
     private static POILogger logger = POILogFactory.getLogger(DataFormatter.class);
-    
+
     /**
      * Creates a formatter using the {@link Locale#getDefault() default locale}.
      */
@@ -281,7 +281,7 @@ public class DataFormatter implements Ob
 
     /**
      * Return a Format for the given cell if one exists, otherwise try to
-     * create one. This method will return <code>null</code> if the any of the
+     * create one. This method will return <code>null</code> if any of the
      * following is true:
      * <ul>
      * <li>the cell's style is null</li>
@@ -294,9 +294,9 @@ public class DataFormatter implements Ob
      */
     private Format getFormat(Cell cell, ConditionalFormattingEvaluator cfEvaluator) {
         if (cell == null) return null;
-        
+
         ExcelNumberFormat numFmt = ExcelNumberFormat.from(cell, cfEvaluator);
-        
+
         if ( numFmt == null) {
             return null;
         }
@@ -316,25 +316,25 @@ public class DataFormatter implements Ob
         }
         return false;
     }
-    
+
     private Format getFormat(double cellValue, int formatIndex, String formatStrIn, boolean use1904Windowing) {
         localeChangedObservable.checkForLocaleChange();
 
         // Might be better to separate out the n p and z formats, falling back to p when n and z are not set.
         // That however would require other code to be re factored.
         // String[] formatBits = formatStrIn.split(";");
-        // int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2; 
+        // int i = cellValue > 0.0 ? 0 : cellValue < 0.0 ? 1 : 2;
         // String formatStr = (i < formatBits.length) ? formatBits[i] : formatBits[0];
 
         String formatStr = formatStrIn;
-        
+
         // Excel supports 2+ part conditional data formats, eg positive/negative/zero,
         //  or (>1000),(>0),(0),(negative). As Java doesn't handle these kinds
-        //  of different formats for different ranges, just +ve/-ve, we need to 
+        //  of different formats for different ranges, just +ve/-ve, we need to
         //  handle these ourselves in a special way.
         // For now, if we detect 2+ parts, we call out to CellFormat to handle it
         // TODO Going forward, we should really merge the logic between the two classes
-        if (formatStr.contains(";") && 
+        if (formatStr.contains(";") &&
                 (formatStr.indexOf(';') != formatStr.lastIndexOf(';')
                  || rangeConditionalPattern.matcher(formatStr).matches()
                 ) ) {
@@ -343,8 +343,8 @@ public class DataFormatter implements Ob
                 CellFormat cfmt = CellFormat.getInstance(locale, formatStr);
                 // CellFormat requires callers to identify date vs not, so do so
                 Object cellValueO = Double.valueOf(cellValue);
-                if (DateUtil.isADateFormat(formatIndex, formatStr) && 
-                        // don't try to handle Date value 0, let a 3 or 4-part format take care of it 
+                if (DateUtil.isADateFormat(formatIndex, formatStr) &&
+                        // don't try to handle Date value 0, let a 3 or 4-part format take care of it
                         ((Double)cellValueO).doubleValue() != 0.0) {
                     cellValueO = DateUtil.getJavaDate(cellValue, use1904Windowing);
                 }
@@ -354,23 +354,23 @@ public class DataFormatter implements Ob
                 logger.log(POILogger.WARN, "Formatting failed for format " + formatStr + ", falling back", e);
             }
         }
-        
+
        // Excel's # with value 0 will output empty where Java will output 0. This hack removes the # from the format.
        if (emulateCSV && cellValue == 0.0 && formatStr.contains("#") && !formatStr.contains("0")) {
            formatStr = formatStr.replaceAll("#", "");
        }
-       
+
         // See if we already have it cached
         Format format = formats.get(formatStr);
         if (format != null) {
             return format;
         }
-        
+
         // Is it one of the special built in types, General or @?
         if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) {
             return generalNumberFormat;
         }
-        
+
         // Build a formatter, and cache it
         format = createFormat(cellValue, formatIndex, formatStr);
         formats.put(formatStr, format);
@@ -393,14 +393,14 @@ public class DataFormatter implements Ob
 
     private Format createFormat(double cellValue, int formatIndex, String sFormat) {
         localeChangedObservable.checkForLocaleChange();
-        
+
         String formatStr = sFormat;
-        
+
         // Remove colour formatting if present
         Matcher colourM = colorPattern.matcher(formatStr);
         while(colourM.find()) {
            String colour = colourM.group();
-           
+
            // Paranoid replacement...
            int at = formatStr.indexOf(colour);
            if(at == -1) break;
@@ -431,7 +431,7 @@ public class DataFormatter implements Ob
         if(formatStr == null || formatStr.trim().length() == 0) {
             return getDefaultFormat(cellValue);
         }
-        
+
         if ("General".equalsIgnoreCase(formatStr) || "@".equals(formatStr)) {
            return generalNumberFormat;
         }
@@ -455,12 +455,12 @@ public class DataFormatter implements Ob
                     return new FractionFormat(wholePart, fractionMatcher.group(3));
                 }
             }
-            
+
             // Strip custom text in quotes and escaped characters for now as it can cause performance problems in fractions.
             //String strippedFormatStr = formatStr.replaceAll("\\\\ ", " ").replaceAll("\\\\.", "").replaceAll("\"[^\"]*\"", " ").replaceAll("\\?", "#");
             return new FractionFormat(defaultFractionWholePartFormat, defaultFractionFractionPartFormat);
         }
-        
+
         if (numPattern.matcher(formatStr).find()) {
             return createNumberFormat(formatStr, cellValue);
         }
@@ -471,8 +471,8 @@ public class DataFormatter implements Ob
         // TODO - when does this occur?
         return null;
     }
-    
- 
+
+
 
     private Format createDateFormat(String pFormatStr, double cellValue) {
         String formatStr = pFormatStr;
@@ -480,7 +480,7 @@ public class DataFormatter implements Ob
         formatStr = formatStr.replaceAll("\\\\,",",");
         formatStr = formatStr.replaceAll("\\\\\\.","."); // . is a special regexp char
         formatStr = formatStr.replaceAll("\\\\ "," ");
-        formatStr = formatStr.replaceAll("\\\\/","/"); // weird: m\\/d\\/yyyy 
+        formatStr = formatStr.replaceAll("\\\\/","/"); // weird: m\\/d\\/yyyy
         formatStr = formatStr.replaceAll(";@", "");
         formatStr = formatStr.replaceAll("\"/\"", "/"); // "/" is escaped for no reason in: mm"/"dd"/"yyyy
         formatStr = formatStr.replace("\"\"", "'");	// replace Excel quoting with Java style quoting
@@ -675,7 +675,7 @@ public class DataFormatter implements Ob
             }
         }
 
-        // Now, handle the other aspects like 
+        // Now, handle the other aspects like
         //  quoting and scientific notation
         for(int i = 0; i < sb.length(); i++) {
            char c = sb.charAt(i);
@@ -748,7 +748,7 @@ public class DataFormatter implements Ob
     private Format createNumberFormat(String formatStr, double cellValue) {
         String format = cleanFormatForNumber(formatStr);
         DecimalFormatSymbols symbols = decimalSymbols;
-        
+
         // Do we need to change the grouping character?
         // eg for a format like #'##0 which wants 12'345 not 12,345
         Matcher agm = alternateGrouping.matcher(format);
@@ -766,7 +766,7 @@ public class DataFormatter implements Ob
                 format = format.replace(oldPart, newPart);
             }
         }
-        
+
         try {
             return new InternalDecimalFormatWithScale(format, symbols);
         } catch(IllegalArgumentException iae) {
@@ -787,7 +787,7 @@ public class DataFormatter implements Ob
     }
     private Format getDefaultFormat(double cellValue) {
         localeChangedObservable.checkForLocaleChange();
-        
+
         // for numeric cells try user supplied default
         if (defaultNumFormat != null) {
             return defaultNumFormat;
@@ -826,6 +826,16 @@ public class DataFormatter implements Ob
             return null;
         }
         Format dateFormat = getFormat(cell, cfEvaluator);
+        if (dateFormat == null) {
+            if (defaultDateformat == null) {
+                DateFormatSymbols sym = DateFormatSymbols.getInstance(LocaleUtil.getUserLocale());
+                SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", sym);
+                sdf.setTimeZone(LocaleUtil.getUserTimeZone());
+                dateFormat = sdf;
+            } else {
+                dateFormat = defaultNumFormat;
+            }
+        }
         synchronized (dateFormat) {
             if(dateFormat instanceof ExcelStyleDateFormatter) {
                 // Hint about the raw excel value
@@ -846,7 +856,7 @@ public class DataFormatter implements Ob
      * <p>
      * Format comes from either the highest priority conditional format rule with a
      * specified format, or from the cell style.
-     * 
+     *
      * @param cell The cell
      * @param cfEvaluator if available, or null
      * @return a formatted number string
@@ -879,7 +889,7 @@ public class DataFormatter implements Ob
      */
     public String formatRawCellContents(double value, int formatIndex, String formatString, boolean use1904Windowing) {
         localeChangedObservable.checkForLocaleChange();
-        
+
         // Is it a date?
         if(DateUtil.isADateFormat(formatIndex,formatString)) {
             if(DateUtil.isValidExcelDate(value)) {
@@ -896,13 +906,13 @@ public class DataFormatter implements Ob
                 return invalidDateTimeString;
             }
         }
-        
+
         // else Number
         Format numberFormat = getFormat(value, formatIndex, formatString, use1904Windowing);
         if (numberFormat == null) {
             return String.valueOf(value);
         }
-        
+
         // When formatting 'value', double to text to BigDecimal produces more
         // accurate results than double to Double in JDK8 (as compared to
         // previous versions). However, if the value contains E notation, this
@@ -960,7 +970,7 @@ public class DataFormatter implements Ob
     public String formatCellValue(Cell cell, FormulaEvaluator evaluator) {
         return formatCellValue(cell, evaluator, null);
     }
-    
+
     /**
      * <p>
      * Returns the formatted value of a cell as a <tt>String</tt> regardless
@@ -990,7 +1000,7 @@ public class DataFormatter implements Ob
      */
     public String formatCellValue(Cell cell, FormulaEvaluator evaluator, ConditionalFormattingEvaluator cfEvaluator) {
         localeChangedObservable.checkForLocaleChange();
-        
+
         if (cell == null) {
             return "";
         }
@@ -1077,9 +1087,9 @@ public class DataFormatter implements Ob
         result.setParseIntegerOnly(true);
         return result;
     }
-    
+
     /**
-     * Enables excel style rounding mode (round half up) on the 
+     * Enables excel style rounding mode (round half up) on the
      *  Decimal Format given.
      */
     public static void setExcelStyleRoundingMode(DecimalFormat format) {
@@ -1119,16 +1129,16 @@ public class DataFormatter implements Ob
         if (!(localeObj instanceof Locale))  return;
         Locale newLocale = (Locale)localeObj;
         if (!localeIsAdapting || newLocale.equals(locale)) return;
-        
+
         locale = newLocale;
-        
+
         dateSymbols = DateFormatSymbols.getInstance(locale);
         decimalSymbols = DecimalFormatSymbols.getInstance(locale);
         generalNumberFormat = new ExcelGeneralNumberFormat(locale);
 
         // taken from Date.toString()
         defaultDateformat = new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy", dateSymbols);
-        defaultDateformat.setTimeZone(LocaleUtil.getUserTimeZone());       
+        defaultDateformat.setTimeZone(LocaleUtil.getUserTimeZone());
 
         // init built-in formats
 
@@ -1262,10 +1272,10 @@ public class DataFormatter implements Ob
             return df.parseObject(source, pos);
         }
     }
-    
 
-    
-    
+
+
+
     /**
      * Format class that does nothing and always returns a constant string.
      *
@@ -1294,7 +1304,7 @@ public class DataFormatter implements Ob
     }
     /**
      * Workaround until we merge {@link DataFormatter} with {@link CellFormat}.
-     * Constant, non-cachable wrapper around a {@link CellFormatResult} 
+     * Constant, non-cachable wrapper around a {@link CellFormatResult}
      */
     @SuppressWarnings("serial")
     private final class CellFormatResultWrapper extends Format {

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/ExcelGeneralNumberFormat.java Sun Dec  8 23:29:50 2019
@@ -16,7 +16,7 @@
 
    2012 - Alfresco Software, Ltd.
    Alfresco Software has modified source of this file
-   The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src 
+   The details of changes as svn diff can be found in svn at location root/projects/3rd-party/src
 ==================================================================== */
 package org.apache.poi.ss.usermodel;
 
@@ -55,6 +55,7 @@ public class ExcelGeneralNumberFormat ex
         DataFormatter.setExcelStyleRoundingMode(decimalFormat);
     }
 
+    @SuppressWarnings("squid:S2111")
     public StringBuffer format(Object number, StringBuffer toAppendTo, FieldPosition pos) {
         final double value;
         if (number instanceof Number) {

Modified: poi/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/usermodel/FractionFormat.java Sun Dec  8 23:29:50 2019
@@ -31,11 +31,11 @@ import org.apache.poi.util.POILogger;
 
 /**
  * <p>Format class that handles Excel style fractions, such as "# #/#" and "#/###"</p>
- * 
+ *
  * <p>As of this writing, this is still not 100% accurate, but it does a reasonable job
  * of trying to mimic Excel's fraction calculations.  It does not currently
  * maintain Excel's spacing.</p>
- * 
+ *
  * <p>This class relies on a method lifted nearly verbatim from org.apache.math.fraction.
  *  If further uses for Commons Math are found, we will consider adding it as a dependency.
  *  For now, we have in-lined the one method to keep things simple.</p>
@@ -43,7 +43,7 @@ import org.apache.poi.util.POILogger;
 
 @SuppressWarnings("serial")
 public class FractionFormat extends Format {
-    private static final POILogger LOGGER = POILogFactory.getLogger(FractionFormat.class); 
+    private static final POILogger LOGGER = POILogFactory.getLogger(FractionFormat.class);
     private static final Pattern DENOM_FORMAT_PATTERN = Pattern.compile("(?:(#+)|(\\d+))");
 
     //this was chosen to match the earlier limitation of max denom power
@@ -78,7 +78,7 @@ public class FractionFormat extends Form
                 try{
                     tmpExact = Integer.parseInt(m.group(2));
                     //if the denom is 0, fall back to the default: tmpExact=100
-                    
+
                     if (tmpExact == 0){
                         tmpExact = -1;
                     }
@@ -104,10 +104,11 @@ public class FractionFormat extends Form
         maxDenom = tmpMax;
     }
 
+    @SuppressWarnings("squid:S2111")
     public String format(Number num) {
 
         final BigDecimal doubleValue = new BigDecimal(num.doubleValue());
-        
+
         final boolean isNeg = doubleValue.compareTo(BigDecimal.ZERO) < 0;
 
         final BigDecimal absValue = doubleValue.abs();
@@ -117,7 +118,7 @@ public class FractionFormat extends Form
         if (wholePart.add(decPart).compareTo(BigDecimal.ZERO) == 0) {
             return "0";
         }
-        
+
         // if the absolute value is smaller than 1 over the exact or maxDenom
         // you can stop here and return "0"
         // reciprocal is result of an int devision ... and so it's nearly always 0
@@ -125,10 +126,10 @@ public class FractionFormat extends Form
         // if (absDoubleValue < reciprocal) {
         //    return "0";
         // }
-        
+
         //this is necessary to prevent overflow in the maxDenom calculation
         if (decPart.compareTo(BigDecimal.ZERO) == 0){
-            
+
             StringBuilder sb = new StringBuilder();
             if (isNeg){
                 sb.append("-");
@@ -136,7 +137,7 @@ public class FractionFormat extends Form
             sb.append(wholePart);
             return sb.toString();
         }
-        
+
         final SimpleFraction fract;
         try {
             //this should be the case because of the constructor
@@ -151,12 +152,12 @@ public class FractionFormat extends Form
         }
 
         StringBuilder sb = new StringBuilder();
-        
+
         //now format the results
         if (isNeg){
             sb.append("-");
         }
-        
+
         //if whole part has to go into the numerator
         if (wholePartFormatString == null || wholePartFormatString.isEmpty()){
             final int fden = fract.getDenominator();
@@ -165,8 +166,8 @@ public class FractionFormat extends Form
             sb.append(trueNum.toBigInteger()).append("/").append(fden);
             return sb.toString();
         }
-        
-        
+
+
         //short circuit if fraction is 0 or 1
         if (fract.getNumerator() == 0){
             sb.append(wholePart);
@@ -190,5 +191,5 @@ public class FractionFormat extends Form
     public Object parseObject(String source, ParsePosition pos) {
         throw new NotImplementedException("Reverse parsing not supported");
     }
-   
+
 }

Modified: poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java?rev=1871064&r1=1871063&r2=1871064&view=diff
==============================================================================
--- poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java (original)
+++ poi/trunk/src/scratchpad/src/org/apache/poi/hemf/record/emfplus/HemfPlusDraw.java Sun Dec  8 23:29:50 2019
@@ -820,7 +820,7 @@ public class HemfPlusDraw {
         }
     }
 
-
+    @SuppressWarnings("squid:S2111")
     static double round10(double d) {
         return new BigDecimal(d).setScale(10, RoundingMode.HALF_UP).doubleValue();
     }



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org