Skip to content

Commit

Permalink
Merge pull request #441 from win32kbase/master
Browse files Browse the repository at this point in the history
Backport alternative class reading method for invalid class CRCs
  • Loading branch information
win32kbase authored Jan 2, 2022
2 parents c8a3cf8 + 235e87a commit 1f8cc84
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 10 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<groupId>me.coley</groupId>
<artifactId>recaf</artifactId>
<url>https://github.com/Col-E/Recaf/</url>
<version>2.21.8</version>
<version>2.21.9</version>
<name>Recaf</name>
<description>A modern java bytecode editor</description>
<!-- Variables -->
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/me/coley/recaf/Recaf.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
* @author Matt
*/
public class Recaf {
public static final String VERSION = "2.21.8";
public static final String VERSION = "2.21.9";
public static final String DOC_URL = "https://col-e.github.io/Recaf-documentation/";
public static final int ASM_VERSION = Opcodes.ASM9;
private static Controller currentController;
Expand Down
45 changes: 37 additions & 8 deletions src/main/java/me/coley/recaf/workspace/JarResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import java.nio.file.Path;
import java.util.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipException;
import java.util.zip.ZipFile;
import java.util.zip.ZipInputStream;

Expand Down Expand Up @@ -34,21 +35,49 @@ protected Map<String, byte[]> loadClasses() throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[8192];
EntryLoader loader = getEntryLoader();
ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()));
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
// verify entries are classes and valid files
// - skip intentional garbage / zip file abnormalities
if (shouldSkip(entry.getName()))
continue;
if (loader.isValidClassEntry(entry)) {

try {
ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()));
ZipEntry entry;

while ((entry = zis.getNextEntry()) != null) {
// verify entries are classes and valid files
// - skip intentional garbage / zip file abnormalities
if (shouldSkip(entry.getName()))
continue;
if (!loader.isValidClassEntry(entry))
continue;

out.reset();
byte[] in = IOUtil.toByteArray(zis, out, buffer);

// There is no possible way a "class" under 30 bytes is valid
if (in.length < 30)
continue;

loader.onClass(entry.getName(), in);
}
} catch (ZipException e) {
if (e.getMessage().contains("invalid entry CRC")) {
// "ZipFile"/"JarFile" reads the entire ZIP file structure before letting us do any entry parsing.
// This may not always be ideal, but this way has one major bonus. It totally ignores CRC validity.
// It also ignores a few other zip entry values.
// Since somebody can intentionally write bogus data there to crash "ZipInputStream" this way works.
ZipFile zf = new ZipFile(getPath().toString());
Enumeration<? extends ZipEntry> entries = zf.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();

if (shouldSkip(entry.getName()))
continue;
if (!loader.isValidClassEntry(entry))
continue;

InputStream zis = zf.getInputStream(entry);
byte[] in = IOUtil.toByteArray(zis);
loader.onClass(entry.getName(), in);
}
}
}
loader.finishClasses();
return loader.getClasses();
Expand Down

0 comments on commit 1f8cc84

Please sign in to comment.