Repository: commons-compress Updated Branches: refs/heads/master 13a039029 -> 08f0aba10
COMPRESS-388: Improve stream performance with wrapped buffers Project: http://git-wip-us.apache.org/repos/asf/commons-compress/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-compress/commit/daa69a59 Tree: http://git-wip-us.apache.org/repos/asf/commons-compress/tree/daa69a59 Diff: http://git-wip-us.apache.org/repos/asf/commons-compress/diff/daa69a59 Branch: refs/heads/master Commit: daa69a5981c7c12e0af5922f0a07653446261b07 Parents: 7e89c9c Author: Zbynek Vyskovsky <kvr...@gmail.com> Authored: Sun Apr 23 20:41:44 2017 -0700 Committer: Stefan Bodewig <bode...@apache.org> Committed: Tue Apr 25 20:02:18 2017 +0200 ---------------------------------------------------------------------- .../commons/compress/archivers/zip/ZipFile.java | 100 +++++++------------ 1 file changed, 37 insertions(+), 63 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-compress/blob/daa69a59/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java index 1bfd753..0623656 100644 --- a/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java +++ b/src/main/java/org/apache/commons/compress/archivers/zip/ZipFile.java @@ -1097,69 +1097,66 @@ public class ZipFile implements Closeable { * range can be read. */ private class BoundedInputStream extends InputStream { - protected static final int MAX_BUF_LEN = 8192; - protected final ByteBuffer buffer; - protected long remaining; - protected long loc; - protected boolean addDummyByte = false; + private ByteBuffer singleByteBuffer; + private final long end; + private long loc; + private boolean addDummy = false; BoundedInputStream(final long start, final long remaining) { - this.remaining = remaining; - loc = start; - if (remaining < MAX_BUF_LEN && remaining > 0) { - buffer = ByteBuffer.allocate((int) remaining); - } else { - buffer = ByteBuffer.allocate(MAX_BUF_LEN); + this.end = start+remaining; + if (this.end < start) { + // check for potential vulnerability due to overflow + throw new IllegalArgumentException("Invalid length of stream at offset="+start+", length="+remaining); } + loc = start; } @Override - public int read() throws IOException { - if (remaining-- <= 0) { - if (addDummyByte) { - addDummyByte = false; + public synchronized int read() throws IOException { + if (loc >= end) { + if (loc == end && addDummy) { + ++loc; return 0; } return -1; } - int read = read(loc++, 1); + if (singleByteBuffer == null) { + singleByteBuffer = ByteBuffer.allocate(1); + } + else { + singleByteBuffer.rewind(); + } + int read = read(loc++, singleByteBuffer); if (read < 0) { return read; } - return buffer.get() & 0xff; + return singleByteBuffer.get() & 0xff; } @Override - public int read(final byte[] b, final int off, int len) throws IOException { - if (remaining <= 0) { - if (addDummyByte) { - addDummyByte = false; - b[off] = 0; - return 1; - } - return -1; - } - + public synchronized int read(final byte[] b, final int off, int len) throws IOException { if (len <= 0) { return 0; } - if (len > remaining) { - len = (int) remaining; + if (len > end-loc) { + if (loc >= end) { + if (loc == end && addDummy) { + ++loc; + b[off] = 0; + return 1; + } + return -1; + } + len = (int)(end-loc); } + ByteBuffer buf; - int ret = -1; - if (len <= buffer.capacity()) { - buf = buffer; - ret = read(loc, len); - } else { - buf = ByteBuffer.allocate(len); - ret = read(loc, buf); - } + buf = ByteBuffer.wrap(b, off, len); + int ret = read(loc, buf); if (ret > 0) { - buf.get(b, off, ret); loc += ret; - remaining -= ret; + return ret; } return ret; } @@ -1174,23 +1171,8 @@ public class ZipFile implements Closeable { return read; } - protected int read(long pos, int len) throws IOException { - int read; - buffer.rewind().limit(len); - synchronized (archive) { - archive.position(pos); - read = archive.read(buffer); - } - buffer.flip(); - return read; - } - - /** - * Inflater needs an extra dummy byte for nowrap - see - * Inflater's javadocs. - */ void addDummy() { - addDummyByte = true; + this.addDummy = true; } } @@ -1214,14 +1196,6 @@ public class ZipFile implements Closeable { buf.flip(); return read; } - - @Override - protected int read(long position, int len) throws IOException { - buffer.rewind().limit(len); - int read = archive.read(buffer, position); - buffer.flip(); - return read; - } } private static final class NameAndComment {