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