diff options
author | Narayan Kamath <narayan@google.com> | 2014-03-11 11:06:19 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-03-11 11:06:20 +0000 |
commit | 43ec94e3875f31cd1cddb3559afca1bea50ed62a (patch) | |
tree | be1160a2e87d716d1ceda8bb8095851970fdda8f /luni | |
parent | 28c889f6de4d9822050e5ce06d367e74b7feb8b4 (diff) | |
parent | bb65253db600d05ca6eeedc6d076f6af20680f99 (diff) | |
download | libcore-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.java | 10 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/util/zip/GZIPInputStreamTest.java | 49 |
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); |