-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathPatchingTests.java
97 lines (87 loc) · 3.47 KB
/
PatchingTests.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package software.coley.lljzip;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import software.coley.lljzip.format.model.ZipArchive;
import software.coley.lljzip.format.transform.IdentityZipPartMapper;
import software.coley.lljzip.format.transform.JvmClassDirectoryMapper;
import software.coley.lljzip.format.write.ZipOutputStreamZipWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import static org.junit.jupiter.api.Assertions.*;
/**
* Tests for patching the <i>"trick"</i> jars, and making them compatible with standard Java ZIP apis.
*
* @author Matt Coley
*/
public class PatchingTests {
// The sample 'hello-merged-fake-empty.jar' is not included because its CEN points to the correct local entry.
// Unlike the samples seen below, it only has one END header, not two.
@ParameterizedTest
@ValueSource(strings = {
"hello-concat.jar",
"hello-concat-junkheader.jar",
"hello-merged.jar",
"hello-merged-junkheader.jar",
})
public void testTrickJarPatched(String name) {
try {
Path path = Paths.get("src/test/resources/" + name);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// Validate the original jar file yields the wrong 'Hello' class
try (ZipInputStream zis = new ZipInputStream(Files.newInputStream(path))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().contains("Hello.class")) {
byte[] buffer = new byte[1024];
baos = new ByteArrayOutputStream();
int len;
while ((len = zis.read(buffer)) > 0)
baos.write(buffer, 0, len);
// The version of 'Hello' read does not contain the right message.
// Running these jars produces the other message, seen below after patching.
Utils.assertDefinesString(baos.toByteArray(), "Hello world!");
}
}
}
// Parse the zip with LL-Java zip, then write back using std java apis
// in order to create a std java compliant jar.
ZipArchive zip = ZipIO.readJvm(path);
new ZipOutputStreamZipWriter().write(zip, baos);
byte[] fixed = baos.toByteArray();
// Validate the new jar bytes can be read and show the true file contents.
try (ZipInputStream zis = new ZipInputStream(new ByteArrayInputStream(fixed))) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (entry.getName().contains("Hello.class")) {
byte[] buffer = new byte[1024];
baos = new ByteArrayOutputStream();
int len;
while ((len = zis.read(buffer)) > 0)
baos.write(buffer, 0, len);
// Now check if the secret code is found.
// If not, we extracted the wrong class.
Utils.assertDefinesString(baos.toByteArray(), "The secret code is: ROSE");
}
}
}
} catch (IOException ex) {
fail(ex);
}
}
@Test
@SuppressWarnings("resource")
public void testTrailingSlashTransform() {
// The 'JvmClassDirectoryMapper' maps 'Name.class/' paths to 'Name.class'
Path path = Paths.get("src/test/resources/hello-secret-trailing-slash.jar");
ZipArchive zip = assertDoesNotThrow(() -> ZipIO.readStandard(path)
.withMapping(new JvmClassDirectoryMapper(new IdentityZipPartMapper())));
assertNotNull(zip.getLocalFileByName("Hello.class"), "Trailing slash was not patched");
}
}