jvmTest.okio.GzipSourceTest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.document.library.opener.onedrive.web
Show all versions of com.liferay.document.library.opener.onedrive.web
Liferay Document Library Opener OneDrive Web
/*
* Copyright (C) 2014 Square, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package okio;
import java.io.IOException;
import java.util.zip.CRC32;
import org.junit.Test;
import static kotlin.text.Charsets.UTF_8;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
public final class GzipSourceTest {
@Test public void gunzip() throws Exception {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeader);
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
@Test public void gunzip_withHCRC() throws Exception {
CRC32 hcrc = new CRC32();
ByteString gzipHeader = gzipHeaderWithFlags((byte) 0x02);
hcrc.update(gzipHeader.toByteArray());
Buffer gzipped = new Buffer();
gzipped.write(gzipHeader);
gzipped.writeShort(TestUtil.reverseBytes((short) hcrc.getValue())); // little endian
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
@Test public void gunzip_withExtra() throws Exception {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeaderWithFlags((byte) 0x04));
gzipped.writeShort(TestUtil.reverseBytes((short) 7)); // little endian extra length
gzipped.write("blubber".getBytes(UTF_8), 0, 7);
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
@Test public void gunzip_withName() throws Exception {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeaderWithFlags((byte) 0x08));
gzipped.write("foo.txt".getBytes(UTF_8), 0, 7);
gzipped.writeByte(0); // zero-terminated
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
@Test public void gunzip_withComment() throws Exception {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeaderWithFlags((byte) 0x10));
gzipped.write("rubbish".getBytes(UTF_8), 0, 7);
gzipped.writeByte(0); // zero-terminated
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
/**
* For portability, it is a good idea to export the gzipped bytes and try running gzip. Ex.
* {@code echo gzipped | base64 --decode | gzip -l -v}
*/
@Test public void gunzip_withAll() throws Exception {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeaderWithFlags((byte) 0x1c));
gzipped.writeShort(TestUtil.reverseBytes((short) 7)); // little endian extra length
gzipped.write("blubber".getBytes(UTF_8), 0, 7);
gzipped.write("foo.txt".getBytes(UTF_8), 0, 7);
gzipped.writeByte(0); // zero-terminated
gzipped.write("rubbish".getBytes(UTF_8), 0, 7);
gzipped.writeByte(0); // zero-terminated
gzipped.write(deflated);
gzipped.write(gzipTrailer);
assertGzipped(gzipped);
}
private void assertGzipped(Buffer gzipped) throws IOException {
Buffer gunzipped = gunzip(gzipped);
assertEquals("It's a UNIX system! I know this!", gunzipped.readUtf8());
}
/**
* Note that you cannot test this with old versions of gzip, as they interpret flag bit 1 as
* CONTINUATION, not HCRC. For example, this is the case with the default gzip on osx.
*/
@Test public void gunzipWhenHeaderCRCIncorrect() {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeaderWithFlags((byte) 0x02));
gzipped.writeShort((short) 0); // wrong HCRC!
gzipped.write(deflated);
gzipped.write(gzipTrailer);
try {
gunzip(gzipped);
fail();
} catch (IOException e) {
assertEquals("FHCRC: actual 0x0000261d != expected 0x00000000", e.getMessage());
}
}
@Test public void gunzipWhenCRCIncorrect() {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeader);
gzipped.write(deflated);
gzipped.writeInt(TestUtil.reverseBytes(0x1234567)); // wrong CRC
gzipped.write(gzipTrailer.toByteArray(), 3, 4);
try {
gunzip(gzipped);
fail();
} catch (IOException e) {
assertEquals("CRC: actual 0x37ad8f8d != expected 0x01234567", e.getMessage());
}
}
@Test public void gunzipWhenLengthIncorrect() {
Buffer gzipped = new Buffer();
gzipped.write(gzipHeader);
gzipped.write(deflated);
gzipped.write(gzipTrailer.toByteArray(), 0, 4);
gzipped.writeInt(TestUtil.reverseBytes(0x123456)); // wrong length
try {
gunzip(gzipped);
fail();
} catch (IOException e) {
assertEquals("ISIZE: actual 0x00000020 != expected 0x00123456", e.getMessage());
}
}
@Test public void gunzipExhaustsSource() throws Exception {
Buffer gzippedSource = new Buffer()
.write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
ExhaustableSource exhaustableSource = new ExhaustableSource(gzippedSource);
BufferedSource gunzippedSource = Okio.buffer(new GzipSource(exhaustableSource));
assertEquals('a', gunzippedSource.readByte());
assertEquals('b', gunzippedSource.readByte());
assertEquals('c', gunzippedSource.readByte());
assertFalse(exhaustableSource.exhausted);
assertEquals(-1, gunzippedSource.read(new Buffer(), 1));
assertTrue(exhaustableSource.exhausted);
}
@Test public void gunzipThrowsIfSourceIsNotExhausted() throws Exception {
Buffer gzippedSource = new Buffer()
.write(ByteString.decodeHex("1f8b08000000000000004b4c4a0600c241243503000000")); // 'abc'
gzippedSource.writeByte('d'); // This byte shouldn't be here!
BufferedSource gunzippedSource = Okio.buffer(new GzipSource(gzippedSource));
assertEquals('a', gunzippedSource.readByte());
assertEquals('b', gunzippedSource.readByte());
assertEquals('c', gunzippedSource.readByte());
try {
gunzippedSource.readByte();
fail();
} catch (IOException expected) {
}
}
private ByteString gzipHeaderWithFlags(byte flags) {
byte[] result = gzipHeader.toByteArray();
result[3] = flags;
return ByteString.of(result);
}
private final ByteString gzipHeader = ByteString.decodeHex("1f8b0800000000000000");
// Deflated "It's a UNIX system! I know this!"
private final ByteString deflated = ByteString.decodeHex(
"f32c512f56485408f5f38c5028ae2c2e49cd5554f054c8cecb2f5728c9c82c560400");
private final ByteString gzipTrailer = ByteString.decodeHex(""
+ "8d8fad37" // Checksum of deflated.
+ "20000000" // 32 in little endian.
);
private Buffer gunzip(Buffer gzipped) throws IOException {
Buffer result = new Buffer();
GzipSource source = new GzipSource(gzipped);
while (source.read(result, Integer.MAX_VALUE) != -1) {
}
return result;
}
/** This source keeps track of whether its read has returned -1. */
static class ExhaustableSource implements Source {
private final Source source;
private boolean exhausted;
ExhaustableSource(Source source) {
this.source = source;
}
@Override public long read(Buffer sink, long byteCount) throws IOException {
long result = source.read(sink, byteCount);
if (result == -1) exhausted = true;
return result;
}
@Override public Timeout timeout() {
return source.timeout();
}
@Override public void close() throws IOException {
source.close();
}
}
}