1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.bcel.verifier;
21
22 import static org.junit.jupiter.api.Assertions.assertEquals;
23 import static org.junit.jupiter.api.Assertions.assertFalse;
24 import static org.junit.jupiter.api.Assertions.assertNotNull;
25 import static org.junit.jupiter.api.Assertions.assertThrowsExactly;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27
28 import java.io.File;
29 import java.io.IOException;
30 import java.net.URISyntaxException;
31 import java.util.Enumeration;
32 import java.util.jar.JarEntry;
33 import java.util.jar.JarFile;
34
35 import org.apache.bcel.classfile.JavaClass;
36 import org.apache.bcel.classfile.NestHost;
37 import org.apache.bcel.classfile.Utility;
38 import org.apache.bcel.verifier.exc.AssertionViolatedException;
39 import org.apache.bcel.verifier.input.FieldVerifierChildClass;
40 import org.apache.bcel.verifier.input.StaticFieldVerifierChildClass;
41 import org.apache.bcel.verifier.statics.StringRepresentation;
42 import org.apache.commons.lang3.Strings;
43 import org.apache.commons.lang3.SystemProperties;
44 import org.junit.jupiter.api.AfterEach;
45 import org.junit.jupiter.api.Test;
46 import org.junit.jupiter.api.condition.DisabledForJreRange;
47 import org.junit.jupiter.api.condition.JRE;
48
49 class VerifierTest {
50
51 private static File getJarFile(final Class<?> clazz) throws URISyntaxException {
52 return new File(clazz.getProtectionDomain().getCodeSource().getLocation().toURI());
53 }
54
55 private static void testDefaultMethodValidation(final String className, final String... excludes) throws ClassNotFoundException {
56 if (Strings.CS.endsWithAny(className, excludes)) {
57 return;
58 }
59 final Verifier verifier = VerifierFactory.getVerifier(className);
60 VerificationResult result = verifier.doPass1();
61
62 assertEquals(VerificationResult.VERIFIED_OK, result.getStatus(), "Pass 1 verification of " + className + " failed: " + result.getMessage());
63
64 result = verifier.doPass2();
65
66 assertEquals(VerificationResult.VERIFIED_OK, result.getStatus(), "Pass 2 verification of " + className + " failed: " + result.getMessage());
67
68 if (result == VerificationResult.VR_OK) {
69 final JavaClass jc = org.apache.bcel.Repository.lookupClass(className);
70 for (int i = 0; i < jc.getMethods().length; i++) {
71 result = verifier.doPass3a(i);
72 assertEquals(VerificationResult.VR_OK, result, "Pass 3a, method number " + i + " ['" + jc.getMethods()[i] + "']:\n" + result);
73 result = verifier.doPass3b(i);
74 assertEquals(VerificationResult.VR_OK, result, "Pass 3b, method number " + i + " ['" + jc.getMethods()[i] + "']:\n" + result);
75 }
76 }
77 }
78
79 private static void testJarFile(final File file, final String... excludes) throws IOException, ClassNotFoundException {
80 try (JarFile jarFile = new JarFile(file)) {
81 final Enumeration<JarEntry> entries = jarFile.entries();
82 while (entries.hasMoreElements()) {
83 final JarEntry jarEntry = entries.nextElement();
84 String entryName = jarEntry.getName();
85 if (entryName.endsWith(JavaClass.EXTENSION)) {
86 entryName = entryName.replaceFirst("\\.class$", "");
87 entryName = Utility.compactClassName(entryName, false);
88 testDefaultMethodValidation(entryName, excludes);
89 }
90 }
91 }
92 }
93
94 private static void testNestHostWithJavaVersion(final String className) throws ClassNotFoundException {
95 final String version = SystemProperties.getJavaVersion();
96 assertNotNull(version);
97 try {
98 testDefaultMethodValidation(className);
99 assertTrue(version.startsWith("1."));
100 } catch (final AssertionViolatedException e) {
101 assertFalse(version.startsWith("1."));
102 final StringBuilder expectedMessage = new StringBuilder();
103 expectedMessage.append("INTERNAL ERROR: Please adapt '");
104 expectedMessage.append(StringRepresentation.class);
105 expectedMessage.append("' to deal with objects of class '");
106 expectedMessage.append(NestHost.class);
107 expectedMessage.append("'.");
108 assertEquals(expectedMessage.toString(), e.getCause().getMessage());
109 }
110 }
111
112 @AfterEach
113 public void afterEach() {
114 VerifierFactory.clear();
115 }
116
117 @Test
118 void testArrayUtils() throws ClassNotFoundException {
119 testNestHostWithJavaVersion("org.apache.commons.lang.ArrayUtils");
120 }
121
122 @Test
123 void testCollection() throws ClassNotFoundException {
124 testDefaultMethodValidation("java.util.Collection");
125 }
126
127 @Test
128 void testCommonsLang2() throws IOException, URISyntaxException, ClassNotFoundException {
129 testJarFile(getJarFile(org.apache.commons.lang.StringUtils.class), "ArrayUtils", "SerializationUtils");
130 }
131
132 @Test
133 void testDefinitionImpl() throws ClassNotFoundException {
134 testNestHostWithJavaVersion("com.ibm.wsdl.DefinitionImpl");
135 }
136
137 @Test
138 void testJvmOpCodes() throws ClassNotFoundException {
139 testDefaultMethodValidation("org.apache.bcel.verifier.tests.JvmOpCodes");
140 }
141
142 @Test
143 @DisabledForJreRange(max = JRE.JAVA_8)
144 void testObjectInputStream() throws ClassNotFoundException {
145 testNestHostWithJavaVersion("java.io.ObjectInputStream");
146 }
147
148 @Test
149 @DisabledForJreRange(min = JRE.JAVA_9)
150 void testObjectInputStreamJDK8() {
151 assertThrowsExactly(UnsupportedOperationException.class, () -> testNestHostWithJavaVersion("java.io.ObjectInputStream"));
152 }
153
154 @Test
155 void testPackagePrivateField() throws ClassNotFoundException {
156 testDefaultMethodValidation(FieldVerifierChildClass.class.getName());
157 }
158
159 @Test
160 void testPackagePrivateStaticField() throws ClassNotFoundException {
161 testDefaultMethodValidation(StaticFieldVerifierChildClass.class.getName());
162 }
163
164 @Test
165 void testWSDL() throws IOException, URISyntaxException, ClassNotFoundException {
166 testJarFile(getJarFile(javax.wsdl.Port.class), "WSDLReaderImpl", "DefinitionImpl");
167 }
168 }