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