Skip to content

Commit 1f8cc84

Browse files
authored
Merge pull request #441 from win32kbase/master
Backport alternative class reading method for invalid class CRCs
2 parents c8a3cf8 + 235e87a commit 1f8cc84

File tree

3 files changed

+39
-10
lines changed

3 files changed

+39
-10
lines changed

pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<groupId>me.coley</groupId>
44
<artifactId>recaf</artifactId>
55
<url>https://github.com/Col-E/Recaf/</url>
6-
<version>2.21.8</version>
6+
<version>2.21.9</version>
77
<name>Recaf</name>
88
<description>A modern java bytecode editor</description>
99
<!-- Variables -->

src/main/java/me/coley/recaf/Recaf.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
* @author Matt
3232
*/
3333
public class Recaf {
34-
public static final String VERSION = "2.21.8";
34+
public static final String VERSION = "2.21.9";
3535
public static final String DOC_URL = "https://col-e.github.io/Recaf-documentation/";
3636
public static final int ASM_VERSION = Opcodes.ASM9;
3737
private static Controller currentController;

src/main/java/me/coley/recaf/workspace/JarResource.java

+37-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.nio.file.Path;
77
import java.util.*;
88
import java.util.zip.ZipEntry;
9+
import java.util.zip.ZipException;
910
import java.util.zip.ZipFile;
1011
import java.util.zip.ZipInputStream;
1112

@@ -34,21 +35,49 @@ protected Map<String, byte[]> loadClasses() throws IOException {
3435
ByteArrayOutputStream out = new ByteArrayOutputStream();
3536
byte[] buffer = new byte[8192];
3637
EntryLoader loader = getEntryLoader();
37-
ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()));
38-
ZipEntry entry;
39-
while ((entry = zis.getNextEntry()) != null) {
40-
// verify entries are classes and valid files
41-
// - skip intentional garbage / zip file abnormalities
42-
if (shouldSkip(entry.getName()))
43-
continue;
44-
if (loader.isValidClassEntry(entry)) {
38+
39+
try {
40+
ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()));
41+
ZipEntry entry;
42+
43+
while ((entry = zis.getNextEntry()) != null) {
44+
// verify entries are classes and valid files
45+
// - skip intentional garbage / zip file abnormalities
46+
if (shouldSkip(entry.getName()))
47+
continue;
48+
if (!loader.isValidClassEntry(entry))
49+
continue;
50+
4551
out.reset();
4652
byte[] in = IOUtil.toByteArray(zis, out, buffer);
53+
4754
// There is no possible way a "class" under 30 bytes is valid
4855
if (in.length < 30)
4956
continue;
57+
5058
loader.onClass(entry.getName(), in);
5159
}
60+
} catch (ZipException e) {
61+
if (e.getMessage().contains("invalid entry CRC")) {
62+
// "ZipFile"/"JarFile" reads the entire ZIP file structure before letting us do any entry parsing.
63+
// This may not always be ideal, but this way has one major bonus. It totally ignores CRC validity.
64+
// It also ignores a few other zip entry values.
65+
// Since somebody can intentionally write bogus data there to crash "ZipInputStream" this way works.
66+
ZipFile zf = new ZipFile(getPath().toString());
67+
Enumeration<? extends ZipEntry> entries = zf.entries();
68+
while (entries.hasMoreElements()) {
69+
ZipEntry entry = entries.nextElement();
70+
71+
if (shouldSkip(entry.getName()))
72+
continue;
73+
if (!loader.isValidClassEntry(entry))
74+
continue;
75+
76+
InputStream zis = zf.getInputStream(entry);
77+
byte[] in = IOUtil.toByteArray(zis);
78+
loader.onClass(entry.getName(), in);
79+
}
80+
}
5281
}
5382
loader.finishClasses();
5483
return loader.getClasses();

0 commit comments

Comments
 (0)