You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@poi.apache.org by ab...@apache.org on 2019/05/21 00:13:51 UTC

svn commit: r1859592 - in /poi/trunk/src/java/org/apache/poi: hssf/record/FilePassRecord.java hssf/record/ObjRecord.java hssf/record/StandardRecord.java hssf/record/cont/ContinuableRecord.java ss/util/CellRangeAddressList.java

Author: abearez
Date: Tue May 21 00:13:51 2019
New Revision: 1859592

URL: http://svn.apache.org/viewvc?rev=1859592&view=rev
Log:
fix potential output resource leaks (LGTM)

Modified:
    poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java
    poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java
    poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java?rev=1859592&r1=1859591&r2=1859592&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/FilePassRecord.java Tue May 21 00:13:51 2019
@@ -43,10 +43,10 @@ public final class FilePassRecord extend
 	public static final short sid = 0x002F;
     private static final int ENCRYPTION_XOR = 0;
     private static final int ENCRYPTION_OTHER = 1;
-	
+
 	private final int encryptionType;
     private EncryptionInfo encryptionInfo;
-	
+
 	private FilePassRecord(FilePassRecord other) {
 	    encryptionType = other.encryptionType;
         try {
@@ -55,15 +55,15 @@ public final class FilePassRecord extend
             throw new EncryptedDocumentException(e);
         }
 	}
-	
+
 	public FilePassRecord(EncryptionMode encryptionMode) {
 	    encryptionType = (encryptionMode == EncryptionMode.xor) ? ENCRYPTION_XOR : ENCRYPTION_OTHER;
 	    encryptionInfo = new EncryptionInfo(encryptionMode);
 	}
-	
+
 	public FilePassRecord(RecordInputStream in) {
 		encryptionType = in.readUShort();
-		
+
 		EncryptionMode preferredMode;
         switch (encryptionType) {
             case ENCRYPTION_XOR:
@@ -75,7 +75,7 @@ public final class FilePassRecord extend
             default:
                 throw new EncryptedDocumentException("invalid encryption type");
         }
-		
+
 		try {
             encryptionInfo = new EncryptionInfo(in, preferredMode);
         } catch (IOException e) {
@@ -88,32 +88,37 @@ public final class FilePassRecord extend
     public void serialize(LittleEndianOutput out) {
         out.writeShort(encryptionType);
 
-        byte[] data = new byte[1024];
-        LittleEndianByteArrayOutputStream bos = new LittleEndianByteArrayOutputStream(data, 0); // NOSONAR
-
-        switch (encryptionInfo.getEncryptionMode()) {
-            case xor:
-                ((XOREncryptionHeader)encryptionInfo.getHeader()).write(bos);
-                ((XOREncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
-                break;
-            case binaryRC4:
-                out.writeShort(encryptionInfo.getVersionMajor());
-                out.writeShort(encryptionInfo.getVersionMinor());
-                ((BinaryRC4EncryptionHeader)encryptionInfo.getHeader()).write(bos);
-                ((BinaryRC4EncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
-                break;
-            case cryptoAPI:
-                out.writeShort(encryptionInfo.getVersionMajor());
-                out.writeShort(encryptionInfo.getVersionMinor());
-                out.writeInt(encryptionInfo.getEncryptionFlags());
-                ((CryptoAPIEncryptionHeader)encryptionInfo.getHeader()).write(bos);
-                ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
-                break;
-            default:
-                throw new EncryptedDocumentException("not supported");
+        byte data[] = new byte[1024];
+        try (LittleEndianByteArrayOutputStream bos =
+                new LittleEndianByteArrayOutputStream(data, 0)) { // NOSONAR
+
+            switch (encryptionInfo.getEncryptionMode()) {
+                case xor:
+                    ((XOREncryptionHeader)encryptionInfo.getHeader()).write(bos);
+                    ((XOREncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+                    break;
+                case binaryRC4:
+                    out.writeShort(encryptionInfo.getVersionMajor());
+                    out.writeShort(encryptionInfo.getVersionMinor());
+                    ((BinaryRC4EncryptionHeader)encryptionInfo.getHeader()).write(bos);
+                    ((BinaryRC4EncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+                    break;
+                case cryptoAPI:
+                    out.writeShort(encryptionInfo.getVersionMajor());
+                    out.writeShort(encryptionInfo.getVersionMinor());
+                    out.writeInt(encryptionInfo.getEncryptionFlags());
+                    ((CryptoAPIEncryptionHeader)encryptionInfo.getHeader()).write(bos);
+                    ((CryptoAPIEncryptionVerifier)encryptionInfo.getVerifier()).write(bos);
+                    break;
+                default:
+                    throw new EncryptedDocumentException("not supported");
+            }
+
+            out.write(data, 0, bos.getWriteIndex());
+        } catch (IOException ioe) {
+            // should never happen in practice
+            throw new IllegalStateException(ioe);
         }
-
-        out.write(data, 0, bos.getWriteIndex());
 	}
 
 	@Override
@@ -132,7 +137,7 @@ public final class FilePassRecord extend
     public short getSid() {
 		return sid;
 	}
-	
+
 	@Override
 	public FilePassRecord clone() {
 		return new FilePassRecord(this);

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java?rev=1859592&r1=1859591&r2=1859592&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/ObjRecord.java Tue May 21 00:13:51 2019
@@ -14,9 +14,10 @@
    See the License for the specific language governing permissions and
    limitations under the License.
 ==================================================================== */
-        
+
 package org.apache.poi.hssf.record;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -28,7 +29,7 @@ import org.apache.poi.util.RecordFormatE
 
 /**
  * OBJRECORD (0x005D)<p>
- * 
+ *
  * The obj record is used to hold various graphic objects and controls.
  */
 public final class ObjRecord extends Record implements Cloneable {
@@ -36,7 +37,7 @@ public final class ObjRecord extends Rec
 
 	private static final int NORMAL_PAD_ALIGNMENT = 2;
 	private static int MAX_PAD_ALIGNMENT = 4;
-	
+
 	private List<SubRecord> subrecords;
 	/** used when POI has no idea what is going on */
 	private final byte[] _uninterpretedData;
@@ -100,7 +101,7 @@ public final class ObjRecord extends Rec
 			_isPaddedToQuadByteMultiple = subRecordData.length % MAX_PAD_ALIGNMENT == 0;
 			if (nRemainingBytes >= (_isPaddedToQuadByteMultiple ? MAX_PAD_ALIGNMENT : NORMAL_PAD_ALIGNMENT)) {
 				if (!canPaddingBeDiscarded(subRecordData, nRemainingBytes)) {
-					String msg = "Leftover " + nRemainingBytes 
+					String msg = "Leftover " + nRemainingBytes
 						+ " bytes in subrecord data " + HexDump.toHex(subRecordData);
 					throw new RecordFormatException(msg);
 				}
@@ -118,7 +119,7 @@ public final class ObjRecord extends Rec
 	 * written by a version of POI (around 3.1) which incorrectly interpreted the second short of
 	 * the ftLbs subrecord (0x1FEE) as a length, and read that many bytes as padding (other bugs
 	 * helped allow this to occur).
-	 * 
+	 *
 	 * Excel reads files with this excessive padding OK, truncating the over-sized ObjRecord back
 	 * to the its proper size.  POI does the same.
 	 */
@@ -145,7 +146,7 @@ public final class ObjRecord extends Rec
 		sb.append("[/OBJ]\n");
 		return sb.toString();
 	}
-	
+
 	@Override
 	public int getRecordSize() {
 		if (_uninterpretedData != null) {
@@ -167,31 +168,35 @@ public final class ObjRecord extends Rec
 		return size + 4;
 	}
 
-	@Override
-	public int serialize(int offset, byte[] data) {
-		int recSize = getRecordSize();
-		int dataSize = recSize - 4;
-		LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize); // NOSONAR
-
-		out.writeShort(sid);
-		out.writeShort(dataSize);
-
-		if (_uninterpretedData == null) {
-
-			for (int i = 0; i < subrecords.size(); i++) {
-				SubRecord record = subrecords.get(i);
-				record.serialize(out);
-			}
-			int expectedEndIx = offset+dataSize;
-			// padding
-			while (out.getWriteIndex() < expectedEndIx) {
-				out.writeByte(0);
-			}
-		} else {
-			out.write(_uninterpretedData);
-		}
-		return recSize;
-	}
+    @Override
+    public int serialize(int offset, byte[] data) {
+        int recSize = getRecordSize();
+        int dataSize = recSize - 4;
+
+        try (LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize)) { // NOSONAR
+            out.writeShort(sid);
+            out.writeShort(dataSize);
+
+            if (_uninterpretedData == null) {
+
+                for (int i = 0; i < subrecords.size(); i++) {
+                    SubRecord record = subrecords.get(i);
+                    record.serialize(out);
+                }
+                int expectedEndIx = offset + dataSize;
+                // padding
+                while (out.getWriteIndex() < expectedEndIx) {
+                    out.writeByte(0);
+                }
+            } else {
+                out.write(_uninterpretedData);
+            }
+        } catch (IOException ioe) {
+            // should never happen in practice
+            throw new IllegalStateException(ioe);
+        }
+        return recSize;
+    }
 
 	@Override
 	public short getSid() {

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java?rev=1859592&r1=1859591&r2=1859592&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/StandardRecord.java Tue May 21 00:13:51 2019
@@ -17,51 +17,62 @@
 
 package org.apache.poi.hssf.record;
 
+import java.io.IOException;
+
 import org.apache.poi.util.LittleEndianByteArrayOutputStream;
 import org.apache.poi.util.LittleEndianOutput;
 
 /**
- * Subclasses of this class (the majority of BIFF records) are non-continuable.  This allows for
- * some simplification of serialization logic
+ * Subclasses of this class (the majority of BIFF records) are non-continuable.
+ * This allows for some simplification of serialization logic
  */
 public abstract class StandardRecord extends Record {
-	protected abstract int getDataSize();
-	public final int getRecordSize() {
-		return 4 + getDataSize();
-	}
+    protected abstract int getDataSize();
+
+    @Override
+    public final int getRecordSize() {
+        return 4 + getDataSize();
+    }
 
     /**
-     * Write the data content of this BIFF record including the sid and record length.
+     * Write the data content of this BIFF record including the sid and record
+     * length.
      * <p>
      * The subclass must write the exact number of bytes as reported by
-     *  {@link org.apache.poi.hssf.record.Record#getRecordSize()}}
+     * {@link org.apache.poi.hssf.record.Record#getRecordSize()}}
      */
-	@Override
-	public final int serialize(int offset, byte[] data) {
-		int dataSize = getDataSize();
-		int recSize = 4 + dataSize;
-		LittleEndianByteArrayOutputStream out = new LittleEndianByteArrayOutputStream(data, offset, recSize);
-		out.writeShort(getSid());
-		out.writeShort(dataSize);
-		serialize(out);
-		if (out.getWriteIndex() - offset != recSize) {
-			throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): "
-					+ "Incorrect number of bytes written - expected "
-					+ recSize + " but got " + (out.getWriteIndex() - offset));
-		}
-		return recSize;
-	}
+    @Override
+    public final int serialize(int offset, byte[] data) {
+        int dataSize = getDataSize();
+        int recSize = 4 + dataSize;
+        try (LittleEndianByteArrayOutputStream out =
+                new LittleEndianByteArrayOutputStream(data, offset, recSize)) {
+            out.writeShort(getSid());
+            out.writeShort(dataSize);
+            serialize(out);
+            if (out.getWriteIndex() - offset != recSize) {
+                throw new IllegalStateException("Error in serialization of (" + getClass().getName() + "): "
+                        + "Incorrect number of bytes written - expected " + recSize + " but got "
+                        + (out.getWriteIndex() - offset));
+            }
+        } catch (IOException ioe) {
+            // should never happen in practice
+            throw new IllegalStateException(ioe);
+        }
+        return recSize;
+    }
 
     /**
-     * Write the data content of this BIFF record.  The 'ushort sid' and 'ushort size' header fields
-     * have already been written by the superclass.
+     * Write the data content of this BIFF record. The 'ushort sid' and 'ushort
+     * size' header fields have already been written by the superclass.
      * <p>
      * The number of bytes written must equal the record size reported by
-     *  {@link org.apache.poi.hssf.record.Record#getRecordSize()}} minus four
-     *  ( record header consisting of a 'ushort sid' and 'ushort reclength' has already been written
-     *  by their superclass).
-     * 
-     * @param out the output object
+     * {@link org.apache.poi.hssf.record.Record#getRecordSize()}} minus four (
+     * record header consisting of a 'ushort sid' and 'ushort reclength' has
+     * already been written by their superclass).
+     *
+     * @param out
+     *            the output object
      */
-	protected abstract void serialize(LittleEndianOutput out);
+    protected abstract void serialize(LittleEndianOutput out);
 }

Modified: poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java?rev=1859592&r1=1859591&r2=1859592&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java (original)
+++ poi/trunk/src/java/org/apache/poi/hssf/record/cont/ContinuableRecord.java Tue May 21 00:13:51 2019
@@ -17,6 +17,8 @@
 
 package org.apache.poi.hssf.record.cont;
 
+import java.io.IOException;
+
 import org.apache.poi.hssf.record.ContinueRecord;
 import org.apache.poi.hssf.record.Record;
 import org.apache.poi.util.LittleEndianByteArrayOutputStream;
@@ -49,6 +51,7 @@ public abstract class ContinuableRecord
 	 * (Note - if any {@link ContinueRecord} is required, this result includes the
 	 * size of those too)
 	 */
+	@Override
 	public final int getRecordSize() {
 		ContinuableRecordOutput out = ContinuableRecordOutput.createForCountingOnly();
 		serialize(out);
@@ -56,12 +59,19 @@ public abstract class ContinuableRecord
 		return out.getTotalSize();
 	}
 
+	@Override
 	public final int serialize(int offset, byte[] data) {
-
-		LittleEndianOutput leo = new LittleEndianByteArrayOutputStream(data, offset);
-		ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid());
-		serialize(out);
-		out.terminate();
-		return out.getTotalSize();
+		int totalSize = 0;
+		try (LittleEndianByteArrayOutputStream leo =
+				new LittleEndianByteArrayOutputStream(data, offset)) {
+			ContinuableRecordOutput out = new ContinuableRecordOutput(leo, getSid());
+			serialize(out);
+			out.terminate();
+			totalSize = out.getTotalSize();
+		} catch (IOException ioe) {
+			// should never happen in practice
+			throw new IllegalStateException(ioe);
+		}
+		return totalSize;
 	}
 }

Modified: poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java?rev=1859592&r1=1859591&r2=1859592&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java (original)
+++ poi/trunk/src/java/org/apache/poi/ss/util/CellRangeAddressList.java Tue May 21 00:13:51 2019
@@ -17,6 +17,7 @@
 
 package org.apache.poi.ss.util;
 
+import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -28,13 +29,13 @@ import org.apache.poi.util.LittleEndianO
  * Implementation of the cell range address lists,like is described
  * in OpenOffice.org's Excel Documentation: excelfileformat.pdf sec 2.5.14 -
  * 'Cell Range Address List'
- * 
+ *
  * In BIFF8 there is a common way to store absolute cell range address lists in
  * several records (not formulas). A cell range address list consists of a field
  * with the number of ranges and the list of the range addresses. Each cell
  * range address (called an ADDR structure) contains 4 16-bit-values.
  * </p>
- * 
+ *
  * @author Dragos Buleandra (dragos.buleandra@trade2b.ro)
  */
 public class CellRangeAddressList {
@@ -48,7 +49,7 @@ public class CellRangeAddressList {
 		_list = new ArrayList<>();
 	}
 	/**
-	 * Convenience constructor for creating a <tt>CellRangeAddressList</tt> with a single 
+	 * Convenience constructor for creating a <tt>CellRangeAddressList</tt> with a single
 	 * <tt>CellRangeAddress</tt>.  Other <tt>CellRangeAddress</tt>es may be added later.
 	 */
 	public CellRangeAddressList(int firstRow, int lastRow, int firstCol, int lastCol) {
@@ -71,7 +72,7 @@ public class CellRangeAddressList {
 	 * structures is automatically set when reading an Excel file and/or
 	 * increased when you manually add a new ADDR structure . This is the reason
 	 * there isn't a set method for this field .
-	 * 
+	 *
 	 * @return number of ADDR structures
 	 */
 	public int countRanges() {
@@ -80,7 +81,7 @@ public class CellRangeAddressList {
 
 	/**
 	 * Add a cell range structure.
-	 * 
+	 *
 	 * @param firstRow - the upper left hand corner's row
 	 * @param firstCol - the upper left hand corner's col
 	 * @param lastRow - the lower right hand corner's row
@@ -98,7 +99,7 @@ public class CellRangeAddressList {
 			throw new RuntimeException("List is empty");
 		}
 		if (rangeIndex < 0 || rangeIndex >= _list.size()) {
-			throw new RuntimeException("Range index (" + rangeIndex 
+			throw new RuntimeException("Range index (" + rangeIndex
 					+ ") is outside allowable range (0.." + (_list.size()-1) + ")");
 		}
 		return _list.remove(rangeIndex);
@@ -124,9 +125,17 @@ public class CellRangeAddressList {
 
 	public int serialize(int offset, byte[] data) {
 		int totalSize = getSize();
-		serialize(new LittleEndianByteArrayOutputStream(data, offset, totalSize));
+		try (LittleEndianByteArrayOutputStream lebaos =
+				new LittleEndianByteArrayOutputStream(data, offset, totalSize)) {
+			serialize(lebaos);
+		}
+		catch (IOException ioe) {
+			// should never happen in practice
+			throw new IllegalStateException(ioe);
+		}
 		return totalSize;
 	}
+
 	public void serialize(LittleEndianOutput out) {
 		int nItems = _list.size();
 		out.writeShort(nItems);
@@ -135,11 +144,10 @@ public class CellRangeAddressList {
 			region.serialize(out);
 		}
 	}
-	
 
 	public CellRangeAddressList copy() {
 		CellRangeAddressList result = new CellRangeAddressList();
-		
+
 		int nItems = _list.size();
 		for (int k = 0; k < nItems; k++) {
 			CellRangeAddress region = _list.get(k);



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