Skip to content

Commit d0cf108

Browse files
committed
Return class header detection back & some fixes
1 parent 41bd61d commit d0cf108

File tree

3 files changed

+35
-11
lines changed

3 files changed

+35
-11
lines changed

src/main/java/me/coley/recaf/util/ClassUtil.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ public static int getVersion(byte[] code) {
298298
* @return {@code true} if data has class magic prefix.
299299
*/
300300
public static boolean isClass(byte[] data) {
301-
return data.length > 4 &&
301+
return data.length >= 4 &&
302302
0xCAFEBABEL == ((
303303
(0xFF & data[0]) << 24L |
304304
(0xFF & data[1]) << 16L |

src/main/java/me/coley/recaf/util/IOUtil.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ private IOUtil() {
4242
public static int transfer(InputStream in, OutputStream out, byte[] buffer, int max) throws IOException {
4343
int transferred = 0;
4444
int r;
45-
while ((max == ANY || max > 0) && (r = in.read(buffer, 0, buffer.length)) != -1) {
45+
while ((max == ANY || max > 0) && (r = in.read(buffer, 0,
46+
max == ANY ? buffer.length : Math.min(buffer.length, max))) != -1) {
4647
transferred += r;
4748
out.write(buffer, 0, r);
4849
if (max != ANY) {

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

+32-9
Original file line numberDiff line numberDiff line change
@@ -36,20 +36,27 @@ protected Map<String, byte[]> loadClasses() throws IOException {
3636
byte[] buffer = new byte[8192];
3737
EntryLoader loader = getEntryLoader();
3838

39-
try {
40-
ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()));
39+
try (ZipInputStream zis = new ZipInputStream(new FileInputStream(getPath().toFile()))) {
4140
ZipEntry entry;
4241

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

5148
out.reset();
52-
byte[] in = IOUtil.toByteArray(zis, out, buffer);
49+
byte[] in;
50+
if (!loader.isValidClassEntry(entry)) {
51+
// The class file might not end with .class or .class/
52+
// so we also check it's header.
53+
in = IOUtil.toByteArray(zis, out, buffer, 4);
54+
if (!loader.isValidClassFile(new ByteArrayInputStream(in))) {
55+
continue;
56+
}
57+
}
58+
59+
in = IOUtil.toByteArray(zis, out, buffer);
5360

5461
// There is no possible way a "class" under 30 bytes is valid
5562
if (in.length < 30)
@@ -70,11 +77,27 @@ protected Map<String, byte[]> loadClasses() throws IOException {
7077

7178
if (shouldSkip(entry.getName()))
7279
continue;
73-
if (!loader.isValidClassEntry(entry))
74-
continue;
7580

76-
InputStream zis = zf.getInputStream(entry);
77-
byte[] in = IOUtil.toByteArray(zis);
81+
out.reset();
82+
byte[] in;
83+
84+
if (!loader.isValidClassEntry(entry)) {
85+
// The class file might not end with .class or .class/
86+
// so we also check it's header.
87+
out.reset();
88+
try (InputStream zis = zf.getInputStream(entry)) {
89+
in = IOUtil.toByteArray(zis, out, buffer, 4);
90+
}
91+
if (!loader.isValidClassFile(new ByteArrayInputStream(in))) {
92+
continue;
93+
}
94+
}
95+
96+
out.reset();
97+
try (InputStream zis = zf.getInputStream(entry)) {
98+
in = IOUtil.toByteArray(zis, out, buffer);
99+
}
100+
78101
loader.onClass(entry.getName(), in);
79102
}
80103
}

0 commit comments

Comments
 (0)