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 {

Reply via email to