Skip to content

Commit

Permalink
Preserve compression method when instrumenting zip entries (#1018)
Browse files Browse the repository at this point in the history
  • Loading branch information
marchof committed Feb 11, 2020
1 parent 71f9341 commit 23c2ca7
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 6 deletions.
Expand Up @@ -26,6 +26,7 @@
import java.io.OutputStream;
import java.io.Serializable;
import java.util.Arrays;
import java.util.zip.CRC32;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
Expand Down Expand Up @@ -250,18 +251,38 @@ public void testInstrumentAll_Class() throws IOException {
public void testInstrumentAll_Zip() throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ZipOutputStream zipout = new ZipOutputStream(buffer);
zipout.putNextEntry(new ZipEntry("Test.class"));

// Compressed Entry
ZipEntry entry = new ZipEntry("TestCompressed.class");
entry.setMethod(ZipEntry.DEFLATED);
zipout.putNextEntry(entry);
zipout.write(TargetLoader.getClassDataAsBytes(getClass()));

// Uncompressed Entry
entry = new ZipEntry("TestUncompressed.class");
entry.setMethod(ZipEntry.STORED);
entry.setSize(TargetLoader.getClassDataAsBytes(getClass()).length);
CRC32 crc = new CRC32();
crc.update(TargetLoader.getClassDataAsBytes(getClass()));
entry.setCrc(crc.getValue());
zipout.putNextEntry(entry);
zipout.write(TargetLoader.getClassDataAsBytes(getClass()));

zipout.finish();
ByteArrayOutputStream out = new ByteArrayOutputStream();

int count = instrumenter.instrumentAll(
new ByteArrayInputStream(buffer.toByteArray()), out, "Test");

assertEquals(1, count);
assertEquals(2, count);
ZipInputStream zipin = new ZipInputStream(
new ByteArrayInputStream(out.toByteArray()));
assertEquals("Test.class", zipin.getNextEntry().getName());
entry = zipin.getNextEntry();
assertEquals("TestCompressed.class", entry.getName());
assertEquals(ZipEntry.DEFLATED, entry.getMethod());
entry = zipin.getNextEntry();
assertEquals("TestUncompressed.class", entry.getName());
assertEquals(ZipEntry.STORED, entry.getMethod());
assertNull(zipin.getNextEntry());
}

Expand Down
40 changes: 37 additions & 3 deletions org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java
Expand Up @@ -16,6 +16,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.CRC32;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
Expand Down Expand Up @@ -216,16 +217,49 @@ private int instrumentZip(final InputStream input,
continue;
}

zipout.putNextEntry(new ZipEntry(entryName));
if (!signatureRemover.filterEntry(entryName, zipin, zipout)) {
count += instrumentAll(zipin, zipout, name + "@" + entryName);
final ZipEntry newEntry = new ZipEntry(entryName);
newEntry.setMethod(entry.getMethod());
switch (entry.getMethod()) {
case ZipEntry.DEFLATED:
zipout.putNextEntry(newEntry);
count += filterOrInstrument(zipin, zipout, name, entryName);
break;
case ZipEntry.STORED:
// Uncompressed entries must be processed in-memory to calculate
// mandatory entry size and CRC
final ByteArrayOutputStream buffer = new ByteArrayOutputStream();
count += filterOrInstrument(zipin, buffer, name, entryName);
final byte[] bytes = buffer.toByteArray();
newEntry.setSize(bytes.length);
newEntry.setCompressedSize(bytes.length);
newEntry.setCrc(crc(bytes));
zipout.putNextEntry(newEntry);
zipout.write(bytes);
break;
default:
throw new AssertionError(entry.getMethod());
}
zipout.closeEntry();
}
zipout.finish();
return count;
}

private int filterOrInstrument(final InputStream in, final OutputStream out,
final String name, final String entryName) throws IOException {
if (signatureRemover.filterEntry(entryName, in, out)) {
return 0;
} else {
return instrumentAll(in, out, name + "@" + entryName);
}
}

private static long crc(final byte[] data) {
final CRC32 crc = new CRC32();
crc.update(data);
return crc.getValue();
}

private ZipEntry nextEntry(final ZipInputStream input,
final String location) throws IOException {
try {
Expand Down
7 changes: 7 additions & 0 deletions org.jacoco.doc/docroot/doc/changes.html
Expand Up @@ -37,6 +37,13 @@ <h3>New Features</h3>
(GitHub <a href="https://github.com/jacoco/jacoco/issues/1016">#1016</a>).</li>
</ul>

<h3>Fixed bugs</h3>
<ul>
<li>Compression method of zip entries is now preserved when instrumenting archives.
This allows to use JaCoCo with frameworks that expect uncompressed entries
(GitHub <a href="https://github.com/jacoco/jacoco/issues/1018">#1018</a>).</li>
</ul>

<h3>Non-functional Changes</h3>
<ul>
<li>Support for Pack200 was removed in JDK 14. JaCoCo will now throw a detailed
Expand Down

0 comments on commit 23c2ca7

Please sign in to comment.