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