diff --git a/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java b/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java index d2427ce15b..a1fdc726f2 100644 --- a/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java +++ b/src/examples/src/org/apache/poi/poifs/poibrowser/TreeReaderListener.java @@ -126,9 +126,10 @@ public class TreeReaderListener implements POIFSReaderListener { DocumentDescriptor d; final DocumentInputStream is = event.getStream(); - if (!is.markSupported()) + if (!is.markSupported()) { throw new UnsupportedOperationException(is.getClass().getName() + " does not support mark()."); + } /* Try do handle this document as a property set. We receive * an exception if is no property set and handle it as a @@ -146,11 +147,7 @@ public class TreeReaderListener implements POIFSReaderListener } catch (Exception t) { - System.err.println - ("Unexpected exception while processing " + - event.getName() + " in " + event.getPath().toString()); - t.printStackTrace(System.err); - throw new RuntimeException(t.getMessage()); + throw new RuntimeException("Unexpected exception while processing " + event.getName() + " in " + event.getPath(), t); } is.close(); @@ -181,9 +178,10 @@ public class TreeReaderListener implements POIFSReaderListener final MutableTreeNode root) { MutableTreeNode n = pathToNode.get(path); - if (n != null) + if (n != null) { /* Node found in map, just return it. */ return n; + } if (path.length() == 0) { /* This is the root path of the POI filesystem. Its tree diff --git a/src/java/org/apache/poi/hpsf/PropertySet.java b/src/java/org/apache/poi/hpsf/PropertySet.java index 30a636ffce..508ede25cf 100644 --- a/src/java/org/apache/poi/hpsf/PropertySet.java +++ b/src/java/org/apache/poi/hpsf/PropertySet.java @@ -37,6 +37,7 @@ import org.apache.poi.poifs.filesystem.Entry; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.LittleEndianConsts; +import org.apache.poi.util.NotImplemented; /** * Represents a property set in the Horrible Property Set Format @@ -419,17 +420,17 @@ public class PropertySet { */ int o = offset; final int byteOrder = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; + o += LittleEndianConsts.SHORT_SIZE; if (byteOrder != BYTE_ORDER_ASSERTION) { return false; } final int format = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; + o += LittleEndianConsts.SHORT_SIZE; if (format != FORMAT_ASSERTION) { return false; } // final long osVersion = LittleEndian.getUInt(src, offset); - o += LittleEndian.INT_SIZE; + o += LittleEndianConsts.INT_SIZE; // final ClassID classID = new ClassID(src, offset); o += ClassID.LENGTH; final long sectionCount = LittleEndian.getUInt(src, o); @@ -460,15 +461,15 @@ public class PropertySet { */ int o = offset; byteOrder = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; + o += LittleEndianConsts.SHORT_SIZE; format = LittleEndian.getUShort(src, o); - o += LittleEndian.SHORT_SIZE; + o += LittleEndianConsts.SHORT_SIZE; osVersion = (int) LittleEndian.getUInt(src, o); - o += LittleEndian.INT_SIZE; + o += LittleEndianConsts.INT_SIZE; classID = new ClassID(src, o); o += ClassID.LENGTH; final int sectionCount = LittleEndian.getInt(src, o); - o += LittleEndian.INT_SIZE; + o += LittleEndianConsts.INT_SIZE; if (sectionCount < 0) { throw new HPSFRuntimeException("Section count " + sectionCount + " is negative."); } @@ -492,7 +493,7 @@ public class PropertySet { */ for (int i = 0; i < sectionCount; i++) { final Section s = new MutableSection(src, o); - o += ClassID.LENGTH + LittleEndian.INT_SIZE; + o += ClassID.LENGTH + LittleEndianConsts.INT_SIZE; sections.add(s); } } @@ -835,6 +836,8 @@ public class PropertySet { /** * @see Object#hashCode() */ + @NotImplemented + @Override public int hashCode() { throw new UnsupportedOperationException("FIXME: Not yet implemented."); } @@ -844,6 +847,7 @@ public class PropertySet { /** * @see Object#toString() */ + @Override public String toString() { final StringBuilder b = new StringBuilder(); final int sectionCount = getSectionCount(); diff --git a/src/java/org/apache/poi/hssf/dev/BiffViewer.java b/src/java/org/apache/poi/hssf/dev/BiffViewer.java index 04e965d441..d6b8777a32 100644 --- a/src/java/org/apache/poi/hssf/dev/BiffViewer.java +++ b/src/java/org/apache/poi/hssf/dev/BiffViewer.java @@ -199,6 +199,7 @@ import org.apache.poi.util.LittleEndian; import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogger; import org.apache.poi.util.StringUtil; +import org.apache.poi.util.SuppressForbidden; /** * Utility for reading in BIFF8 records and displaying data from them. @@ -612,7 +613,9 @@ public final class BiffViewer { public void processRecord(int globalOffset, int recordCounter, int sid, int dataSize, byte[] data) { String header = formatRecordDetails(globalOffset, sid, dataSize, recordCounter); - if(!_noHeader) _headers.add(header); + if(!_noHeader) { + _headers.add(header); + } Writer w = _hexDumpWriter; if (w != null) { try { @@ -708,6 +711,7 @@ public final class BiffViewer { } @Override + @SuppressForbidden("just delegating the call") public int available() throws IOException { return _currentSize - _currentPos + _is.available(); } diff --git a/src/java/org/apache/poi/hssf/record/ObjRecord.java b/src/java/org/apache/poi/hssf/record/ObjRecord.java index 5220f9cc07..df5f047b5e 100644 --- a/src/java/org/apache/poi/hssf/record/ObjRecord.java +++ b/src/java/org/apache/poi/hssf/record/ObjRecord.java @@ -58,12 +58,10 @@ public final class ObjRecord extends Record implements Cloneable { public ObjRecord(RecordInputStream in) { // TODO - problems with OBJ sub-records stream // MS spec says first sub-record is always CommonObjectDataSubRecord, - // and last is - // always EndSubRecord. OOO spec does not mention ObjRecord(0x005D). + // and last is always EndSubRecord. OOO spec does not mention ObjRecord(0x005D). // Existing POI test data seems to violate that rule. Some test data - // seems to contain - // garbage, and a crash is only averted by stopping at what looks like - // the 'EndSubRecord' + // seems to contain garbage, and a crash is only averted by stopping at + // what looks like the 'EndSubRecord' // Check if this can be continued, if so then the // following wont work properly @@ -141,10 +139,9 @@ public final class ObjRecord extends Record implements Cloneable { sb.append("[OBJ]\n"); if(subrecords != null) { // there are special cases where this can be, see comments in constructor above - for (int i = 0; i < subrecords.size(); i++) { - SubRecord record = subrecords.get(i); - sb.append("SUBRECORD: ").append(record.toString()); - } + for (final SubRecord record : subrecords) { + sb.append("SUBRECORD: ").append(record.toString()); + } } sb.append("[/OBJ]\n"); return sb.toString(); @@ -156,8 +153,7 @@ public final class ObjRecord extends Record implements Cloneable { return _uninterpretedData.length + 4; } int size = 0; - for (int i=subrecords.size()-1; i>=0; i--) { - SubRecord record = subrecords.get(i); + for (SubRecord record : subrecords) { size += record.getDataSize()+4; } if (_isPaddedToQuadByteMultiple) { @@ -203,6 +199,7 @@ public final class ObjRecord extends Record implements Cloneable { return sid; } + // FIXME: return Collections.unmodifiableList? public List getSubRecords() { return subrecords; } @@ -223,9 +220,8 @@ public final class ObjRecord extends Record implements Cloneable { public ObjRecord clone() { ObjRecord rec = new ObjRecord(); - for (int i = 0; i < subrecords.size(); i++) { - SubRecord record = subrecords.get(i); - rec.addSubRecord((SubRecord) record.clone()); + for (SubRecord record : subrecords) { + rec.addSubRecord(record.clone()); } return rec; } diff --git a/src/java/org/apache/poi/hssf/record/SubRecord.java b/src/java/org/apache/poi/hssf/record/SubRecord.java index 35b62c36c5..2f74b5996b 100644 --- a/src/java/org/apache/poi/hssf/record/SubRecord.java +++ b/src/java/org/apache/poi/hssf/record/SubRecord.java @@ -84,10 +84,12 @@ public abstract class SubRecord { } public abstract void serialize(LittleEndianOutput out); - public abstract Object clone(); + + @Override + public abstract SubRecord clone(); /** - * Wether this record terminates the sub-record stream. + * Whether this record terminates the sub-record stream. * There are two cases when this method must be overridden and return true * - EndSubRecord (sid = 0x00) * - LbsDataSubRecord (sid = 0x12) @@ -109,19 +111,23 @@ public abstract class SubRecord { in.readFully(buf); _data = buf; } + @Override protected int getDataSize() { return _data.length; } + @Override public void serialize(LittleEndianOutput out) { out.writeShort(_sid); out.writeShort(_data.length); out.write(_data); } - public Object clone() { + @Override + public UnknownSubRecord clone() { return this; } + @Override public String toString() { - StringBuffer sb = new StringBuffer(64); + StringBuilder sb = new StringBuilder(64); sb.append(getClass().getName()).append(" ["); sb.append("sid=").append(HexDump.shortToHex(_sid)); sb.append(" size=").append(_data.length); diff --git a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java index ffc4e600f9..73834e1570 100644 --- a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java +++ b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherInputStream.java @@ -76,11 +76,9 @@ public abstract class ChunkedCipherInputStream extends LittleEndianInputStream { @Override public int read() throws IOException { - byte[] b = new byte[1]; - if (read(b) == 1) { - return b[0]; - } - return -1; + byte[] b = { 0 }; + // FIXME: compare against -1 or 1? + return (read(b) == -1) ? -1 : b[0]; } // do not implement! -> recursion diff --git a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java index dbbc8a5d53..65579bebe7 100644 --- a/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java +++ b/src/java/org/apache/poi/poifs/crypt/ChunkedCipherOutputStream.java @@ -64,6 +64,7 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream { // the cipher can't be final, because for the last chunk we change the padding // and therefore need to change the cipher too private Cipher cipher; + private boolean isClosed = false; public ChunkedCipherOutputStream(DirectoryNode dir, int chunkSize) throws IOException, GeneralSecurityException { super(null); @@ -224,6 +225,13 @@ public abstract class ChunkedCipherOutputStream extends FilterOutputStream { @Override public void close() throws IOException { + if (isClosed) { + LOG.log(POILogger.DEBUG, "ChunkedCipherOutputStream was already closed - ignoring"); + return; + } + + isClosed = true; + try { writeChunk(false); diff --git a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java index b82e61a934..633feba62d 100644 --- a/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java +++ b/src/java/org/apache/poi/poifs/eventfilesystem/POIFSReader.java @@ -30,6 +30,7 @@ import org.apache.poi.poifs.filesystem.POIFSDocumentPath; import org.apache.poi.poifs.property.DirectoryProperty; import org.apache.poi.poifs.property.Property; import org.apache.poi.poifs.property.PropertyTable; +import org.apache.poi.poifs.property.RootProperty; import org.apache.poi.poifs.storage.BlockAllocationTableReader; import org.apache.poi.poifs.storage.BlockList; import org.apache.poi.poifs.storage.HeaderBlock; @@ -94,13 +95,15 @@ public class POIFSReader new PropertyTable(header_block, data_blocks); // process documents + RootProperty root = properties.getRoot(); processProperties(SmallBlockTableReader .getSmallDocumentBlocks( header_block.getBigBlockSize(), - data_blocks, properties.getRoot(), - header_block.getSBATStart()), - data_blocks, properties.getRoot() - .getChildren(), new POIFSDocumentPath()); + data_blocks, root, + header_block.getSBATStart() + ), + data_blocks, root.getChildren(), new POIFSDocumentPath() + ); } /** diff --git a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java index ffd6a1a85f..c77ce9e046 100644 --- a/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/DocumentInputStream.java @@ -21,6 +21,7 @@ import java.io.IOException; import java.io.InputStream; import org.apache.poi.util.LittleEndianInput; +import org.apache.poi.util.SuppressForbidden; /** * This class provides methods to read a DocumentEntry managed by a @@ -86,6 +87,7 @@ public class DocumentInputStream extends InputStream implements LittleEndianInpu } @Override + @SuppressForbidden("just delegating") public int available() { return delegate.available(); } diff --git a/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java index d193b05ca1..5c9d35da23 100644 --- a/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/NDocumentInputStream.java @@ -40,13 +40,13 @@ public final class NDocumentInputStream extends DocumentInputStream { private int _marked_offset_count; /** the Document's size */ - private int _document_size; + private final int _document_size; /** have we been closed? */ private boolean _closed; /** the actual Document */ - private NPOIFSDocument _document; + private final NPOIFSDocument _document; private Iterator _data; private ByteBuffer _buffer; @@ -97,6 +97,15 @@ public final class NDocumentInputStream extends DocumentInputStream { @Override public int available() { + return remainingBytes(); + } + + /** + * Helper methods for forbidden api calls + * + * @return the bytes remaining until the end of the stream + */ + private int remainingBytes() { if (_closed) { throw new IllegalStateException("cannot perform requested operation on a closed stream"); } @@ -146,7 +155,7 @@ public final class NDocumentInputStream extends DocumentInputStream { if (atEOD()) { return EOF; } - int limit = Math.min(available(), len); + int limit = Math.min(remainingBytes(), len); readFully(b, off, limit); return limit; } @@ -297,13 +306,13 @@ public final class NDocumentInputStream extends DocumentInputStream { return LittleEndian.getUShort(data); } - @Override - public int readUByte() { - checkAvaliable(1); - byte[] data = new byte[1]; - readFully(data, 0, 1); - if(data[0] >= 0) - return data[0]; - return data[0] + 256; - } + @Override + public int readUByte() { + checkAvaliable(1); + byte[] data = new byte[1]; + readFully(data, 0, 1); + if (data[0] >= 0) + return data[0]; + return data[0] + 256; + } } diff --git a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java index 858e2d9d9b..9b6ce33f46 100644 --- a/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java +++ b/src/java/org/apache/poi/poifs/filesystem/ODocumentInputStream.java @@ -33,13 +33,13 @@ public final class ODocumentInputStream extends DocumentInputStream { private int _marked_offset; /** the Document's size */ - private int _document_size; + private final int _document_size; /** have we been closed? */ private boolean _closed; /** the actual Document */ - private OPOIFSDocument _document; + private final OPOIFSDocument _document; /** the data block containing the current stream pointer */ private DataInputBlock _currentBlock; diff --git a/src/java/org/apache/poi/util/LittleEndianInputStream.java b/src/java/org/apache/poi/util/LittleEndianInputStream.java index 3062c50ff4..3109f88b2c 100644 --- a/src/java/org/apache/poi/util/LittleEndianInputStream.java +++ b/src/java/org/apache/poi/util/LittleEndianInputStream.java @@ -26,8 +26,6 @@ import java.io.InputStream; * * This class does not buffer any input, so the stream read position maintained * by this class is consistent with that of the inner stream. - * - * @author Josh Micich */ public class LittleEndianInputStream extends FilterInputStream implements LittleEndianInput { public LittleEndianInputStream(InputStream is) { @@ -35,7 +33,8 @@ public class LittleEndianInputStream extends FilterInputStream implements Little } @Override - public int available() { + @SuppressForbidden("just delegating") + public int available() { try { return super.available(); } catch (IOException e) { @@ -44,12 +43,12 @@ public class LittleEndianInputStream extends FilterInputStream implements Little } @Override - public byte readByte() { + public byte readByte() { return (byte)readUByte(); } @Override - public int readUByte() { + public int readUByte() { byte buf[] = new byte[1]; try { checkEOF(read(buf), 1); @@ -60,15 +59,15 @@ public class LittleEndianInputStream extends FilterInputStream implements Little } @Override - public double readDouble() { + public double readDouble() { return Double.longBitsToDouble(readLong()); } @Override - public int readInt() { - byte buf[] = new byte[LittleEndianConsts.INT_SIZE]; + public int readInt() { + byte buf[] = new byte[LittleEndianConsts.INT_SIZE]; try { - checkEOF(read(buf), buf.length); + checkEOF(read(buf), buf.length); } catch (IOException e) { throw new RuntimeException(e); } @@ -82,13 +81,14 @@ public class LittleEndianInputStream extends FilterInputStream implements Little * @exception RuntimeException * wraps any IOException thrown from reading the stream. */ + //@Override public long readUInt() { long retNum = readInt(); return retNum & 0x00FFFFFFFFL; } @Override - public long readLong() { + public long readLong() { byte buf[] = new byte[LittleEndianConsts.LONG_SIZE]; try { checkEOF(read(buf), LittleEndianConsts.LONG_SIZE); @@ -99,12 +99,12 @@ public class LittleEndianInputStream extends FilterInputStream implements Little } @Override - public short readShort() { + public short readShort() { return (short)readUShort(); } @Override - public int readUShort() { + public int readUShort() { byte buf[] = new byte[LittleEndianConsts.SHORT_SIZE]; try { checkEOF(read(buf), LittleEndianConsts.SHORT_SIZE); @@ -120,19 +120,19 @@ public class LittleEndianInputStream extends FilterInputStream implements Little } } - @Override + @Override public void readFully(byte[] buf) { - readFully(buf, 0, buf.length); - } + readFully(buf, 0, buf.length); + } - @Override + @Override public void readFully(byte[] buf, int off, int len) { - try { - checkEOF(read(buf, off, len), len); - } catch (IOException e) { + try { + checkEOF(read(buf, off, len), len); + } catch (IOException e) { throw new RuntimeException(e); } - } + } @Override public void readPlain(byte[] buf, int off, int len) { diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java index b674b3ad2f..9ed602603e 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/ZipHelper.java @@ -42,6 +42,7 @@ import org.apache.poi.poifs.common.POIFSConstants; import org.apache.poi.poifs.storage.HeaderBlockConstants; import org.apache.poi.util.IOUtils; import org.apache.poi.util.LittleEndian; +import org.apache.poi.util.Removal; public final class ZipHelper { /** @@ -54,7 +55,11 @@ public final class ZipHelper { * Buffer to read data from file. Use big buffer to improve performaces. the * InputStream class is reading only 8192 bytes per read call (default value * set by sun) + * + * @deprecated in POI 3.16-beta3, not used anymore */ + @Deprecated + @Removal(version="3.18") public static final int READ_WRITE_FILE_BUFFER_SIZE = 8192; /** @@ -74,8 +79,9 @@ public final class ZipHelper { PackageRelationship corePropsRel = pkg.getRelationshipsByType( PackageRelationshipTypes.CORE_PROPERTIES).getRelationship(0); - if (corePropsRel == null) + if (corePropsRel == null) { return null; + } return new ZipEntry(corePropsRel.getTargetURI().getPath()); } @@ -91,8 +97,9 @@ public final class ZipHelper { while (entries.hasMoreElements()) { ZipEntry entry = entries.nextElement(); if (entry.getName().equals( - ContentTypeManager.CONTENT_TYPES_PART_NAME)) + ContentTypeManager.CONTENT_TYPES_PART_NAME)) { return entry; + } } return null; } @@ -106,8 +113,9 @@ public final class ZipHelper { * @return An OPC compliant name. */ public static String getOPCNameFromZipItemName(String zipItemName) { - if (zipItemName == null) - throw new IllegalArgumentException("zipItemName"); + if (zipItemName == null) { + throw new IllegalArgumentException("zipItemName cannot be null"); + } if (zipItemName.startsWith(FORWARD_SLASH)) { return zipItemName; } @@ -123,12 +131,14 @@ public final class ZipHelper { * @return A zip item name without any leading slashes. */ public static String getZipItemNameFromOPCName(String opcItemName) { - if (opcItemName == null) - throw new IllegalArgumentException("opcItemName"); + if (opcItemName == null) { + throw new IllegalArgumentException("opcItemName cannot be null"); + } String retVal = opcItemName; - while (retVal.startsWith(FORWARD_SLASH)) + while (retVal.startsWith(FORWARD_SLASH)) { retVal = retVal.substring(1); + } return retVal; } @@ -141,12 +151,14 @@ public final class ZipHelper { * @return A zip URI without any leading slashes. */ public static URI getZipURIFromOPCName(String opcItemName) { - if (opcItemName == null) + if (opcItemName == null) { throw new IllegalArgumentException("opcItemName"); + } String retVal = opcItemName; - while (retVal.startsWith(FORWARD_SLASH)) + while (retVal.startsWith(FORWARD_SLASH)) { retVal = retVal.substring(1); + } try { return new URI(retVal); } catch (URISyntaxException e) { diff --git a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java index 37abb44293..7ef469edcd 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/opc/internal/marshallers/ZipPartMarshaller.java @@ -44,8 +44,6 @@ import org.w3c.dom.Element; /** * Zip part marshaller. This marshaller is use to save any part in a zip stream. - * - * @author Julien Chable */ public final class ZipPartMarshaller implements PartMarshaller { private final static POILogger logger = POILogFactory.getLogger(ZipPartMarshaller.class); @@ -56,6 +54,7 @@ public final class ZipPartMarshaller implements PartMarshaller { * @throws OpenXML4JException * Throws if an internal exception is thrown. */ + @Override public boolean marshall(PackagePart part, OutputStream os) throws OpenXML4JException { if (!(os instanceof ZipOutputStream)) { diff --git a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java index ef5c5378e8..47af1bde74 100644 --- a/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java +++ b/src/ooxml/java/org/apache/poi/openxml4j/util/ZipSecureFile.java @@ -160,6 +160,7 @@ public class ZipSecureFile extends ZipFile { * @throws IOException if an I/O error has occurred * @throws IllegalStateException if the zip file has been closed */ + @Override @SuppressWarnings("resource") public InputStream getInputStream(ZipEntry entry) throws IOException { InputStream zipIS = super.getInputStream(entry); @@ -170,6 +171,7 @@ public class ZipSecureFile extends ZipFile { ThresholdInputStream newInner; if (zipIS instanceof InflaterInputStream) { newInner = AccessController.doPrivileged(new PrivilegedAction() { // NOSONAR + @Override @SuppressForbidden("TODO: Fix this to not use reflection (it will break in Java 9)! " + "Better would be to wrap *before* instead of trying to insert wrapper afterwards.") public ThresholdInputStream run() { @@ -177,9 +179,9 @@ public class ZipSecureFile extends ZipFile { Field f = FilterInputStream.class.getDeclaredField("in"); f.setAccessible(true); InputStream oldInner = (InputStream)f.get(zipIS); - ThresholdInputStream newInner = new ThresholdInputStream(oldInner, null); - f.set(zipIS, newInner); - return newInner; + ThresholdInputStream newInner2 = new ThresholdInputStream(oldInner, null); + f.set(zipIS, newInner2); + return newInner2; } catch (Exception ex) { LOG.log(POILogger.WARN, "SecurityManager doesn't allow manipulation via reflection for zipbomb detection - continue with original input stream", ex); } @@ -203,24 +205,31 @@ public class ZipSecureFile extends ZipFile { this.cis = cis; } + @Override public int read() throws IOException { int b = in.read(); - if (b > -1) advance(1); + if (b > -1) { + advance(1); + } return b; } + @Override public int read(byte b[], int off, int len) throws IOException { int cnt = in.read(b, off, len); - if (cnt > -1) advance(cnt); + if (cnt > -1) { + advance(cnt); + } return cnt; - } + @Override public long skip(long n) throws IOException { counter = 0; return in.skip(n); } + @Override public synchronized void reset() throws IOException { counter = 0; in.reset(); @@ -277,31 +286,41 @@ public class ZipSecureFile extends ZipFile { ((ZipInputStream)in).closeEntry(); } + @Override public void unread(int b) throws IOException { if (!(in instanceof PushbackInputStream)) { throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream"); } - if (--counter < 0) counter = 0; + if (--counter < 0) { + counter = 0; + } ((PushbackInputStream)in).unread(b); } + @Override public void unread(byte[] b, int off, int len) throws IOException { if (!(in instanceof PushbackInputStream)) { throw new UnsupportedOperationException("underlying stream is not a PushbackInputStream"); } counter -= len; - if (--counter < 0) counter = 0; + if (--counter < 0) { + counter = 0; + } ((PushbackInputStream)in).unread(b, off, len); } + @Override + @SuppressForbidden("just delegating") public int available() throws IOException { return in.available(); } + @Override public boolean markSupported() { return in.markSupported(); } + @Override public synchronized void mark(int readlimit) { in.mark(readlimit); } diff --git a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java index 2dcbcf0e94..4ccd0b1aeb 100644 --- a/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java +++ b/src/ooxml/testcases/org/apache/poi/poifs/crypt/TestDecryptor.java @@ -50,6 +50,8 @@ public class TestDecryptor { Decryptor d = Decryptor.getInstance(info); assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD)); + + fs.close(); } @Test @@ -63,6 +65,8 @@ public class TestDecryptor { d.verifyPassword(Decryptor.DEFAULT_PASSWORD); zipOk(fs.getRoot(), d); + + fs.close(); } @Test @@ -78,6 +82,8 @@ public class TestDecryptor { assertTrue(d.verifyPassword(Decryptor.DEFAULT_PASSWORD)); zipOk(fs.getRoot(), d); + + fs.close(); } private void zipOk(DirectoryNode root, Decryptor d) throws IOException, GeneralSecurityException { @@ -85,9 +91,13 @@ public class TestDecryptor { while (true) { ZipEntry entry = zin.getNextEntry(); - if (entry==null) break; + if (entry==null) { + break; + } // crc32 is checked within zip-stream - if (entry.isDirectory()) continue; + if (entry.isDirectory()) { + continue; + } zin.skip(entry.getSize()); byte buf[] = new byte[10]; int readBytes = zin.read(buf); @@ -182,4 +192,4 @@ public class TestDecryptor { fs.close(); } -} \ No newline at end of file +}