summaryrefslogtreecommitdiffstats
path: root/luni
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2014-03-11 11:06:19 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-03-11 11:06:20 +0000
commit43ec94e3875f31cd1cddb3559afca1bea50ed62a (patch)
treebe1160a2e87d716d1ceda8bb8095851970fdda8f /luni
parent28c889f6de4d9822050e5ce06d367e74b7feb8b4 (diff)
parentbb65253db600d05ca6eeedc6d076f6af20680f99 (diff)
downloadlibcore-43ec94e3875f31cd1cddb3559afca1bea50ed62a.zip
libcore-43ec94e3875f31cd1cddb3559afca1bea50ed62a.tar.gz
libcore-43ec94e3875f31cd1cddb3559afca1bea50ed62a.tar.bz2
Merge "Use the correct buffer size for the Pushback stream."
Diffstat (limited to 'luni')
-rw-r--r--luni/src/main/java/java/util/zip/GZIPInputStream.java10
-rw-r--r--luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java49
2 files changed, 56 insertions, 3 deletions
diff --git a/luni/src/main/java/java/util/zip/GZIPInputStream.java b/luni/src/main/java/java/util/zip/GZIPInputStream.java
index 790adb2..1bfc496 100644
--- a/luni/src/main/java/java/util/zip/GZIPInputStream.java
+++ b/luni/src/main/java/java/util/zip/GZIPInputStream.java
@@ -166,10 +166,14 @@ public class GZIPInputStream extends InflaterInputStream {
// successfully consumed the GZIP trailer.
final int remaining = inf.getRemaining() - GZIP_TRAILER_SIZE;
if (remaining > 0) {
- // NOTE: This prevents us from creating multiple layers of nested
- // PushbackInputStreams if we have multiple members in this stream.
+ // NOTE: We make sure we create a pushback stream exactly once,
+ // even if the input stream contains multiple members.
+ //
+ // The push back stream we create must therefore be able to contain
+ // (worst case) the entire buffer even though there may be fewer bytes
+ // remaining when it is first created.
if (!(in instanceof PushbackInputStream)) {
- in = new PushbackInputStream(in, BUF_SIZE);
+ in = new PushbackInputStream(in, buf.length);
}
((PushbackInputStream) in).unread(buf,
inf.getCurrentOffset() + GZIP_TRAILER_SIZE, remaining);
diff --git a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
index b2e012e..494520a 100644
--- a/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
+++ b/luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java
@@ -19,12 +19,18 @@ package libcore.java.util.zip;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.EOFException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.Random;
import java.util.zip.GZIPInputStream;
+import java.util.zip.GZIPOutputStream;
import junit.framework.TestCase;
+import libcore.io.IoUtils;
+import libcore.io.Streams;
public final class GZIPInputStreamTest extends TestCase {
@@ -112,6 +118,49 @@ public final class GZIPInputStreamTest extends TestCase {
}
}
+ // https://code.google.com/p/android/issues/detail?id=66409
+ public void testMultipleMembersWithCustomBufferSize() throws Exception {
+ final int[] memberSizes = new int[] { 1000, 2000 };
+
+ // We don't care what the exact contents of this file is, as long
+ // as the file has multiple members, and that the (compressed) size of
+ // the second member is larger than the size of the input buffer.
+ //
+ // There's no way to achieve this for a GZIPOutputStream so we generate
+ // pseudo-random sequence of bytes and assert that they don't compress
+ // well.
+ final Random r = new Random(10);
+ byte[] bytes = new byte[3000];
+ r.nextBytes(bytes);
+
+ File f = File.createTempFile("GZIPInputStreamTest", ".gzip");
+ int offset = 0;
+ for (int size : memberSizes) {
+ GZIPOutputStream gzos = null;
+ try {
+ FileOutputStream fos = new FileOutputStream(f, true /* append */);
+ gzos = new GZIPOutputStream(fos, size + 1);
+ gzos.write(bytes, offset, size);
+ offset += size;
+ gzos.finish();
+ } finally {
+ IoUtils.closeQuietly(gzos);
+ }
+ }
+
+ assertTrue(f.length() > 2048);
+
+ FileInputStream fis = new FileInputStream(f);
+ GZIPInputStream gzip = null;
+ try {
+ gzip = new GZIPInputStream(fis, memberSizes[0]);
+ byte[] unzipped = Streams.readFully(gzip);
+ assertTrue(Arrays.equals(bytes, unzipped));
+ } finally {
+ IoUtils.closeQuietly(gzip);
+ }
+ }
+
public static byte[] gunzip(byte[] bytes) throws IOException {
ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
InputStream in = new GZIPInputStream(bis);